libspatialite-5.1.0/ 0000755 0001750 0001750 00000000000 14463127126 011352 5 0000000 0000000 libspatialite-5.1.0/m4/ 0000755 0001750 0001750 00000000000 14463127115 011670 5 0000000 0000000 libspatialite-5.1.0/m4/libtool.m4 0000644 0001750 0001750 00001125306 14463127014 013524 0000000 0000000 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
m4_define([_LT_COPYING], [dnl
# Copyright (C) 2014 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions. There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# GNU Libtool 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 2 of of the License, or
# (at your option) any later version.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program or library that is built
# using GNU Libtool, you may include this file under the same
# distribution terms that you use for the rest of that program.
#
# GNU Libtool 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 .
])
# serial 58 LT_INIT
# LT_PREREQ(VERSION)
# ------------------
# Complain and exit if this libtool version is less that VERSION.
m4_defun([LT_PREREQ],
[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
[m4_default([$3],
[m4_fatal([Libtool version $1 or higher is required],
63)])],
[$2])])
# _LT_CHECK_BUILDDIR
# ------------------
# Complain if the absolute build directory name contains unusual characters
m4_defun([_LT_CHECK_BUILDDIR],
[case `pwd` in
*\ * | *\ *)
AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
esac
])
# LT_INIT([OPTIONS])
# ------------------
AC_DEFUN([LT_INIT],
[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_BEFORE([$0], [LT_LANG])dnl
AC_BEFORE([$0], [LT_OUTPUT])dnl
AC_BEFORE([$0], [LTDL_INIT])dnl
m4_require([_LT_CHECK_BUILDDIR])dnl
dnl Autoconf doesn't catch unexpanded LT_ macros by default:
m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
dnl unless we require an AC_DEFUNed macro:
AC_REQUIRE([LTOPTIONS_VERSION])dnl
AC_REQUIRE([LTSUGAR_VERSION])dnl
AC_REQUIRE([LTVERSION_VERSION])dnl
AC_REQUIRE([LTOBSOLETE_VERSION])dnl
m4_require([_LT_PROG_LTMAIN])dnl
_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
dnl Parse OPTIONS
_LT_SET_OPTIONS([$0], [$1])
# This can be used to rebuild libtool when needed
LIBTOOL_DEPS=$ltmain
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
AC_SUBST(LIBTOOL)dnl
_LT_SETUP
# Only expand once:
m4_define([LT_INIT])
])# LT_INIT
# Old names:
AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
# _LT_PREPARE_CC_BASENAME
# -----------------------
m4_defun([_LT_PREPARE_CC_BASENAME], [
# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
func_cc_basename ()
{
for cc_temp in @S|@*""; do
case $cc_temp in
compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
\-*) ;;
*) break;;
esac
done
func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
}
])# _LT_PREPARE_CC_BASENAME
# _LT_CC_BASENAME(CC)
# -------------------
# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
# but that macro is also expanded into generated libtool script, which
# arranges for $SED and $ECHO to be set by different means.
m4_defun([_LT_CC_BASENAME],
[m4_require([_LT_PREPARE_CC_BASENAME])dnl
AC_REQUIRE([_LT_DECL_SED])dnl
AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
func_cc_basename $1
cc_basename=$func_cc_basename_result
])
# _LT_FILEUTILS_DEFAULTS
# ----------------------
# It is okay to use these file commands and assume they have been set
# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
m4_defun([_LT_FILEUTILS_DEFAULTS],
[: ${CP="cp -f"}
: ${MV="mv -f"}
: ${RM="rm -f"}
])# _LT_FILEUTILS_DEFAULTS
# _LT_SETUP
# ---------
m4_defun([_LT_SETUP],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
dnl
_LT_DECL([], [host_alias], [0], [The host system])dnl
_LT_DECL([], [host], [0])dnl
_LT_DECL([], [host_os], [0])dnl
dnl
_LT_DECL([], [build_alias], [0], [The build system])dnl
_LT_DECL([], [build], [0])dnl
_LT_DECL([], [build_os], [0])dnl
dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([LT_PATH_LD])dnl
AC_REQUIRE([LT_PATH_NM])dnl
dnl
AC_REQUIRE([AC_PROG_LN_S])dnl
test -z "$LN_S" && LN_S="ln -s"
_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
dnl
AC_REQUIRE([LT_CMD_MAX_LEN])dnl
_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
m4_require([_LT_CMD_RELOAD])dnl
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
m4_require([_LT_WITH_SYSROOT])dnl
m4_require([_LT_CMD_TRUNCATE])dnl
_LT_CONFIG_LIBTOOL_INIT([
# See if we are running on zsh, and set the options that allow our
# commands through without removal of \ escapes INIT.
if test -n "\${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
])
if test -n "${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
_LT_CHECK_OBJDIR
m4_require([_LT_TAG_COMPILER])dnl
case $host_os in
aix3*)
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
if test set != "${COLLECT_NAMES+set}"; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
;;
esac
# Global variables:
ofile=libtool
can_build_shared=yes
# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
with_gnu_ld=$lt_cv_prog_gnu_ld
old_CC=$CC
old_CFLAGS=$CFLAGS
# Set sane defaults for various variables
test -z "$CC" && CC=cc
test -z "$LTCC" && LTCC=$CC
test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
test -z "$LD" && LD=ld
test -z "$ac_objext" && ac_objext=o
_LT_CC_BASENAME([$compiler])
# Only perform the check for file, if the check method requires it
test -z "$MAGIC_CMD" && MAGIC_CMD=file
case $deplibs_check_method in
file_magic*)
if test "$file_magic_cmd" = '$MAGIC_CMD'; then
_LT_PATH_MAGIC
fi
;;
esac
# Use C for the default configuration in the libtool script
LT_SUPPORTED_TAG([CC])
_LT_LANG_C_CONFIG
_LT_LANG_DEFAULT_CONFIG
_LT_CONFIG_COMMANDS
])# _LT_SETUP
# _LT_PREPARE_SED_QUOTE_VARS
# --------------------------
# Define a few sed substitution that help us do robust quoting.
m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
[# Backslashify metacharacters that are still active within
# double-quoted strings.
sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
# Same as above, but do not quote variable references.
double_quote_subst='s/\([["`\\]]\)/\\\1/g'
# Sed substitution to delay expansion of an escaped shell variable in a
# double_quote_subst'ed string.
delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
# Sed substitution to delay expansion of an escaped single quote.
delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
# Sed substitution to avoid accidental globbing in evaled expressions
no_glob_subst='s/\*/\\\*/g'
])
# _LT_PROG_LTMAIN
# ---------------
# Note that this code is called both from 'configure', and 'config.status'
# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
# 'config.status' has no value for ac_aux_dir unless we are using Automake,
# so we pass a copy along to make sure it has a sensible value anyway.
m4_defun([_LT_PROG_LTMAIN],
[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
ltmain=$ac_aux_dir/ltmain.sh
])# _LT_PROG_LTMAIN
## ------------------------------------- ##
## Accumulate code for creating libtool. ##
## ------------------------------------- ##
# So that we can recreate a full libtool script including additional
# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
# in macros and then make a single call at the end using the 'libtool'
# label.
# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
# ----------------------------------------
# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
m4_define([_LT_CONFIG_LIBTOOL_INIT],
[m4_ifval([$1],
[m4_append([_LT_OUTPUT_LIBTOOL_INIT],
[$1
])])])
# Initialize.
m4_define([_LT_OUTPUT_LIBTOOL_INIT])
# _LT_CONFIG_LIBTOOL([COMMANDS])
# ------------------------------
# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
m4_define([_LT_CONFIG_LIBTOOL],
[m4_ifval([$1],
[m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
[$1
])])])
# Initialize.
m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
# -----------------------------------------------------
m4_defun([_LT_CONFIG_SAVE_COMMANDS],
[_LT_CONFIG_LIBTOOL([$1])
_LT_CONFIG_LIBTOOL_INIT([$2])
])
# _LT_FORMAT_COMMENT([COMMENT])
# -----------------------------
# Add leading comment marks to the start of each line, and a trailing
# full-stop to the whole comment if one is not present already.
m4_define([_LT_FORMAT_COMMENT],
[m4_ifval([$1], [
m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
[['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
)])
## ------------------------ ##
## FIXME: Eliminate VARNAME ##
## ------------------------ ##
# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
# -------------------------------------------------------------------
# CONFIGNAME is the name given to the value in the libtool script.
# VARNAME is the (base) name used in the configure script.
# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
# VARNAME. Any other value will be used directly.
m4_define([_LT_DECL],
[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
[lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
[m4_ifval([$1], [$1], [$2])])
lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
m4_ifval([$4],
[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
lt_dict_add_subkey([lt_decl_dict], [$2],
[tagged?], [m4_ifval([$5], [yes], [no])])])
])
# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
# --------------------------------------------------------
m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
# ------------------------------------------------
m4_define([lt_decl_tag_varnames],
[_lt_decl_filter([tagged?], [yes], $@)])
# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
# ---------------------------------------------------------
m4_define([_lt_decl_filter],
[m4_case([$#],
[0], [m4_fatal([$0: too few arguments: $#])],
[1], [m4_fatal([$0: too few arguments: $#: $1])],
[2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
[3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
[lt_dict_filter([lt_decl_dict], $@)])[]dnl
])
# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
# --------------------------------------------------
m4_define([lt_decl_quote_varnames],
[_lt_decl_filter([value], [1], $@)])
# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
# ---------------------------------------------------
m4_define([lt_decl_dquote_varnames],
[_lt_decl_filter([value], [2], $@)])
# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
# ---------------------------------------------------
m4_define([lt_decl_varnames_tagged],
[m4_assert([$# <= 2])dnl
_$0(m4_quote(m4_default([$1], [[, ]])),
m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
m4_define([_lt_decl_varnames_tagged],
[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
# ------------------------------------------------
m4_define([lt_decl_all_varnames],
[_$0(m4_quote(m4_default([$1], [[, ]])),
m4_if([$2], [],
m4_quote(lt_decl_varnames),
m4_quote(m4_shift($@))))[]dnl
])
m4_define([_lt_decl_all_varnames],
[lt_join($@, lt_decl_varnames_tagged([$1],
lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
])
# _LT_CONFIG_STATUS_DECLARE([VARNAME])
# ------------------------------------
# Quote a variable value, and forward it to 'config.status' so that its
# declaration there will have the same value as in 'configure'. VARNAME
# must have a single quote delimited value for this to work.
m4_define([_LT_CONFIG_STATUS_DECLARE],
[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
# _LT_CONFIG_STATUS_DECLARATIONS
# ------------------------------
# We delimit libtool config variables with single quotes, so when
# we write them to config.status, we have to be sure to quote all
# embedded single quotes properly. In configure, this macro expands
# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
#
# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`'
m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
[m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
# _LT_LIBTOOL_TAGS
# ----------------
# Output comment and list of tags supported by the script
m4_defun([_LT_LIBTOOL_TAGS],
[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
available_tags='_LT_TAGS'dnl
])
# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
# -----------------------------------
# Extract the dictionary values for VARNAME (optionally with TAG) and
# expand to a commented shell variable setting:
#
# # Some comment about what VAR is for.
# visible_name=$lt_internal_name
m4_define([_LT_LIBTOOL_DECLARE],
[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
[description])))[]dnl
m4_pushdef([_libtool_name],
m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
[0], [_libtool_name=[$]$1],
[1], [_libtool_name=$lt_[]$1],
[2], [_libtool_name=$lt_[]$1],
[_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
])
# _LT_LIBTOOL_CONFIG_VARS
# -----------------------
# Produce commented declarations of non-tagged libtool config variables
# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
# section) are produced by _LT_LIBTOOL_TAG_VARS.
m4_defun([_LT_LIBTOOL_CONFIG_VARS],
[m4_foreach([_lt_var],
m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
[m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
# _LT_LIBTOOL_TAG_VARS(TAG)
# -------------------------
m4_define([_LT_LIBTOOL_TAG_VARS],
[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
[m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
# _LT_TAGVAR(VARNAME, [TAGNAME])
# ------------------------------
m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
# _LT_CONFIG_COMMANDS
# -------------------
# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
# variables for single and double quote escaping we saved from calls
# to _LT_DECL, we can put quote escaped variables declarations
# into 'config.status', and then the shell code to quote escape them in
# for loops in 'config.status'. Finally, any additional code accumulated
# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
m4_defun([_LT_CONFIG_COMMANDS],
[AC_PROVIDE_IFELSE([LT_OUTPUT],
dnl If the libtool generation code has been placed in $CONFIG_LT,
dnl instead of duplicating it all over again into config.status,
dnl then we will have config.status run $CONFIG_LT later, so it
dnl needs to know what name is stored there:
[AC_CONFIG_COMMANDS([libtool],
[$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
dnl If the libtool generation code is destined for config.status,
dnl expand the accumulated commands and init code now:
[AC_CONFIG_COMMANDS([libtool],
[_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
])#_LT_CONFIG_COMMANDS
# Initialize.
m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
[
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
sed_quote_subst='$sed_quote_subst'
double_quote_subst='$double_quote_subst'
delay_variable_subst='$delay_variable_subst'
_LT_CONFIG_STATUS_DECLARATIONS
LTCC='$LTCC'
LTCFLAGS='$LTCFLAGS'
compiler='$compiler_DEFAULT'
# A function that is used when there is no print builtin or printf.
func_fallback_echo ()
{
eval 'cat <<_LTECHO_EOF
\$[]1
_LTECHO_EOF'
}
# Quote evaled strings.
for var in lt_decl_all_varnames([[ \
]], lt_decl_quote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
;;
esac
done
# Double-quote double-evaled strings.
for var in lt_decl_all_varnames([[ \
]], lt_decl_dquote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
;;
esac
done
_LT_OUTPUT_LIBTOOL_INIT
])
# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
# ------------------------------------
# Generate a child script FILE with all initialization necessary to
# reuse the environment learned by the parent script, and make the
# file executable. If COMMENT is supplied, it is inserted after the
# '#!' sequence but before initialization text begins. After this
# macro, additional text can be appended to FILE to form the body of
# the child script. The macro ends with non-zero status if the
# file could not be fully written (such as if the disk is full).
m4_ifdef([AS_INIT_GENERATED],
[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
[m4_defun([_LT_GENERATED_FILE_INIT],
[m4_require([AS_PREPARE])]dnl
[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
[lt_write_fail=0
cat >$1 <<_ASEOF || lt_write_fail=1
#! $SHELL
# Generated by $as_me.
$2
SHELL=\${CONFIG_SHELL-$SHELL}
export SHELL
_ASEOF
cat >>$1 <<\_ASEOF || lt_write_fail=1
AS_SHELL_SANITIZE
_AS_PREPARE
exec AS_MESSAGE_FD>&1
_ASEOF
test 0 = "$lt_write_fail" && chmod +x $1[]dnl
m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
# LT_OUTPUT
# ---------
# This macro allows early generation of the libtool script (before
# AC_OUTPUT is called), incase it is used in configure for compilation
# tests.
AC_DEFUN([LT_OUTPUT],
[: ${CONFIG_LT=./config.lt}
AC_MSG_NOTICE([creating $CONFIG_LT])
_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
[# Run this file to recreate a libtool stub with the current configuration.])
cat >>"$CONFIG_LT" <<\_LTEOF
lt_cl_silent=false
exec AS_MESSAGE_LOG_FD>>config.log
{
echo
AS_BOX([Running $as_me.])
} >&AS_MESSAGE_LOG_FD
lt_cl_help="\
'$as_me' creates a local libtool stub from the current configuration,
for use in further configure time tests before the real libtool is
generated.
Usage: $[0] [[OPTIONS]]
-h, --help print this help, then exit
-V, --version print version number, then exit
-q, --quiet do not print progress messages
-d, --debug don't remove temporary files
Report bugs to ."
lt_cl_version="\
m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
configured by $[0], generated by m4_PACKAGE_STRING.
Copyright (C) 2011 Free Software Foundation, Inc.
This config.lt script is free software; the Free Software Foundation
gives unlimited permision to copy, distribute and modify it."
while test 0 != $[#]
do
case $[1] in
--version | --v* | -V )
echo "$lt_cl_version"; exit 0 ;;
--help | --h* | -h )
echo "$lt_cl_help"; exit 0 ;;
--debug | --d* | -d )
debug=: ;;
--quiet | --q* | --silent | --s* | -q )
lt_cl_silent=: ;;
-*) AC_MSG_ERROR([unrecognized option: $[1]
Try '$[0] --help' for more information.]) ;;
*) AC_MSG_ERROR([unrecognized argument: $[1]
Try '$[0] --help' for more information.]) ;;
esac
shift
done
if $lt_cl_silent; then
exec AS_MESSAGE_FD>/dev/null
fi
_LTEOF
cat >>"$CONFIG_LT" <<_LTEOF
_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
_LTEOF
cat >>"$CONFIG_LT" <<\_LTEOF
AC_MSG_NOTICE([creating $ofile])
_LT_OUTPUT_LIBTOOL_COMMANDS
AS_EXIT(0)
_LTEOF
chmod +x "$CONFIG_LT"
# configure is writing to config.log, but config.lt does its own redirection,
# appending to config.log, which fails on DOS, as config.log is still kept
# open by configure. Here we exec the FD to /dev/null, effectively closing
# config.log, so it can be properly (re)opened and appended to by config.lt.
lt_cl_success=:
test yes = "$silent" &&
lt_config_lt_args="$lt_config_lt_args --quiet"
exec AS_MESSAGE_LOG_FD>/dev/null
$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
exec AS_MESSAGE_LOG_FD>>config.log
$lt_cl_success || AS_EXIT(1)
])# LT_OUTPUT
# _LT_CONFIG(TAG)
# ---------------
# If TAG is the built-in tag, create an initial libtool script with a
# default configuration from the untagged config vars. Otherwise add code
# to config.status for appending the configuration named by TAG from the
# matching tagged config vars.
m4_defun([_LT_CONFIG],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
_LT_CONFIG_SAVE_COMMANDS([
m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
m4_if(_LT_TAG, [C], [
# See if we are running on zsh, and set the options that allow our
# commands through without removal of \ escapes.
if test -n "${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
cfgfile=${ofile}T
trap "$RM \"$cfgfile\"; exit 1" 1 2 15
$RM "$cfgfile"
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
# Written by Gordon Matzigkeit, 1996
_LT_COPYING
_LT_LIBTOOL_TAGS
# Configured defaults for sys_lib_dlsearch_path munging.
: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
# ### BEGIN LIBTOOL CONFIG
_LT_LIBTOOL_CONFIG_VARS
_LT_LIBTOOL_TAG_VARS
# ### END LIBTOOL CONFIG
_LT_EOF
cat <<'_LT_EOF' >> "$cfgfile"
# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
_LT_PREPARE_MUNGE_PATH_LIST
_LT_PREPARE_CC_BASENAME
# ### END FUNCTIONS SHARED WITH CONFIGURE
_LT_EOF
case $host_os in
aix3*)
cat <<\_LT_EOF >> "$cfgfile"
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
if test set != "${COLLECT_NAMES+set}"; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
_LT_EOF
;;
esac
_LT_PROG_LTMAIN
# We use sed instead of cat because bash on DJGPP gets confused if
# if finds mixed CR/LF and LF-only lines. Since sed operates in
# text mode, it properly converts lines to CR/LF. This bash problem
# is reportedly fixed, but why not run on old versions too?
sed '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
],
[cat <<_LT_EOF >> "$ofile"
dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
dnl in a comment (ie after a #).
# ### BEGIN LIBTOOL TAG CONFIG: $1
_LT_LIBTOOL_TAG_VARS(_LT_TAG)
# ### END LIBTOOL TAG CONFIG: $1
_LT_EOF
])dnl /m4_if
],
[m4_if([$1], [], [
PACKAGE='$PACKAGE'
VERSION='$VERSION'
RM='$RM'
ofile='$ofile'], [])
])dnl /_LT_CONFIG_SAVE_COMMANDS
])# _LT_CONFIG
# LT_SUPPORTED_TAG(TAG)
# ---------------------
# Trace this macro to discover what tags are supported by the libtool
# --tag option, using:
# autoconf --trace 'LT_SUPPORTED_TAG:$1'
AC_DEFUN([LT_SUPPORTED_TAG], [])
# C support is built-in for now
m4_define([_LT_LANG_C_enabled], [])
m4_define([_LT_TAGS], [])
# LT_LANG(LANG)
# -------------
# Enable libtool support for the given language if not already enabled.
AC_DEFUN([LT_LANG],
[AC_BEFORE([$0], [LT_OUTPUT])dnl
m4_case([$1],
[C], [_LT_LANG(C)],
[C++], [_LT_LANG(CXX)],
[Go], [_LT_LANG(GO)],
[Java], [_LT_LANG(GCJ)],
[Fortran 77], [_LT_LANG(F77)],
[Fortran], [_LT_LANG(FC)],
[Windows Resource], [_LT_LANG(RC)],
[m4_ifdef([_LT_LANG_]$1[_CONFIG],
[_LT_LANG($1)],
[m4_fatal([$0: unsupported language: "$1"])])])dnl
])# LT_LANG
# _LT_LANG(LANGNAME)
# ------------------
m4_defun([_LT_LANG],
[m4_ifdef([_LT_LANG_]$1[_enabled], [],
[LT_SUPPORTED_TAG([$1])dnl
m4_append([_LT_TAGS], [$1 ])dnl
m4_define([_LT_LANG_]$1[_enabled], [])dnl
_LT_LANG_$1_CONFIG($1)])dnl
])# _LT_LANG
m4_ifndef([AC_PROG_GO], [
############################################################
# NOTE: This macro has been submitted for inclusion into #
# GNU Autoconf as AC_PROG_GO. When it is available in #
# a released version of Autoconf we should remove this #
# macro and use it instead. #
############################################################
m4_defun([AC_PROG_GO],
[AC_LANG_PUSH(Go)dnl
AC_ARG_VAR([GOC], [Go compiler command])dnl
AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
_AC_ARG_VAR_LDFLAGS()dnl
AC_CHECK_TOOL(GOC, gccgo)
if test -z "$GOC"; then
if test -n "$ac_tool_prefix"; then
AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
fi
fi
if test -z "$GOC"; then
AC_CHECK_PROG(GOC, gccgo, gccgo, false)
fi
])#m4_defun
])#m4_ifndef
# _LT_LANG_DEFAULT_CONFIG
# -----------------------
m4_defun([_LT_LANG_DEFAULT_CONFIG],
[AC_PROVIDE_IFELSE([AC_PROG_CXX],
[LT_LANG(CXX)],
[m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
AC_PROVIDE_IFELSE([AC_PROG_F77],
[LT_LANG(F77)],
[m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
AC_PROVIDE_IFELSE([AC_PROG_FC],
[LT_LANG(FC)],
[m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
dnl pulling things in needlessly.
AC_PROVIDE_IFELSE([AC_PROG_GCJ],
[LT_LANG(GCJ)],
[AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
[LT_LANG(GCJ)],
[AC_PROVIDE_IFELSE([LT_PROG_GCJ],
[LT_LANG(GCJ)],
[m4_ifdef([AC_PROG_GCJ],
[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
m4_ifdef([A][M_PROG_GCJ],
[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
m4_ifdef([LT_PROG_GCJ],
[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
AC_PROVIDE_IFELSE([AC_PROG_GO],
[LT_LANG(GO)],
[m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
AC_PROVIDE_IFELSE([LT_PROG_RC],
[LT_LANG(RC)],
[m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
])# _LT_LANG_DEFAULT_CONFIG
# Obsolete macros:
AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
dnl AC_DEFUN([AC_LIBTOOL_F77], [])
dnl AC_DEFUN([AC_LIBTOOL_FC], [])
dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
dnl AC_DEFUN([AC_LIBTOOL_RC], [])
# _LT_TAG_COMPILER
# ----------------
m4_defun([_LT_TAG_COMPILER],
[AC_REQUIRE([AC_PROG_CC])dnl
_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
# If no C compiler flags were specified, use CFLAGS.
LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
# Allow CC to be a program name with arguments.
compiler=$CC
])# _LT_TAG_COMPILER
# _LT_COMPILER_BOILERPLATE
# ------------------------
# Check for compiler boilerplate output or warnings with
# the simple compiler test code.
m4_defun([_LT_COMPILER_BOILERPLATE],
[m4_require([_LT_DECL_SED])dnl
ac_outfile=conftest.$ac_objext
echo "$lt_simple_compile_test_code" >conftest.$ac_ext
eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
_lt_compiler_boilerplate=`cat conftest.err`
$RM conftest*
])# _LT_COMPILER_BOILERPLATE
# _LT_LINKER_BOILERPLATE
# ----------------------
# Check for linker boilerplate output or warnings with
# the simple link test code.
m4_defun([_LT_LINKER_BOILERPLATE],
[m4_require([_LT_DECL_SED])dnl
ac_outfile=conftest.$ac_objext
echo "$lt_simple_link_test_code" >conftest.$ac_ext
eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
_lt_linker_boilerplate=`cat conftest.err`
$RM -r conftest*
])# _LT_LINKER_BOILERPLATE
# _LT_REQUIRED_DARWIN_CHECKS
# -------------------------
m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
case $host_os in
rhapsody* | darwin*)
AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
AC_CHECK_TOOL([LIPO], [lipo], [:])
AC_CHECK_TOOL([OTOOL], [otool], [:])
AC_CHECK_TOOL([OTOOL64], [otool64], [:])
_LT_DECL([], [DSYMUTIL], [1],
[Tool to manipulate archived DWARF debug symbol files on Mac OS X])
_LT_DECL([], [NMEDIT], [1],
[Tool to change global to local symbols on Mac OS X])
_LT_DECL([], [LIPO], [1],
[Tool to manipulate fat objects and archives on Mac OS X])
_LT_DECL([], [OTOOL], [1],
[ldd/readelf like tool for Mach-O binaries on Mac OS X])
_LT_DECL([], [OTOOL64], [1],
[ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
[lt_cv_apple_cc_single_mod=no
if test -z "$LT_MULTI_MODULE"; then
# By default we will add the -single_module flag. You can override
# by either setting the environment variable LT_MULTI_MODULE
# non-empty at configure time, or by adding -multi_module to the
# link flags.
rm -rf libconftest.dylib*
echo "int foo(void){return 1;}" > conftest.c
echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
-dynamiclib -Wl,-single_module conftest.c 2>conftest.err
_lt_result=$?
# If there is a non-empty error log, and "single_module"
# appears in it, assume the flag caused a linker warning
if test -s conftest.err && $GREP single_module conftest.err; then
cat conftest.err >&AS_MESSAGE_LOG_FD
# Otherwise, if the output was created with a 0 exit code from
# the compiler, it worked.
elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
fi
rm -rf libconftest.dylib*
rm -f conftest.*
fi])
AC_CACHE_CHECK([for -exported_symbols_list linker flag],
[lt_cv_ld_exported_symbols_list],
[lt_cv_ld_exported_symbols_list=no
save_LDFLAGS=$LDFLAGS
echo "_main" > conftest.sym
LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
[lt_cv_ld_exported_symbols_list=yes],
[lt_cv_ld_exported_symbols_list=no])
LDFLAGS=$save_LDFLAGS
])
AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
[lt_cv_ld_force_load=no
cat > conftest.c << _LT_EOF
int forced_loaded() { return 2;}
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
cat > conftest.c << _LT_EOF
int main() { return 0;}
_LT_EOF
echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
_lt_result=$?
if test -s conftest.err && $GREP force_load conftest.err; then
cat conftest.err >&AS_MESSAGE_LOG_FD
elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
lt_cv_ld_force_load=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
fi
rm -f conftest.err libconftest.a conftest conftest.c
rm -rf conftest.dSYM
])
case $host_os in
rhapsody* | darwin1.[[012]])
_lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
darwin1.*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[[012]][[,.]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
10.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
if test yes = "$lt_cv_apple_cc_single_mod"; then
_lt_dar_single_mod='$single_module'
fi
if test yes = "$lt_cv_ld_exported_symbols_list"; then
_lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
else
_lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
fi
if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
fi
;;
esac
])
# _LT_DARWIN_LINKER_FEATURES([TAG])
# ---------------------------------
# Checks for linker and compiler features on darwin
m4_defun([_LT_DARWIN_LINKER_FEATURES],
[
m4_require([_LT_REQUIRED_DARWIN_CHECKS])
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
if test yes = "$lt_cv_ld_force_load"; then
_LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
[FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=''
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
case $cc_basename in
ifort*|nagfor*) _lt_dar_can_shared=yes ;;
*) _lt_dar_can_shared=$GCC ;;
esac
if test yes = "$_lt_dar_can_shared"; then
output_verbose_link_cmd=func_echo_all
_LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
_LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
m4_if([$1], [CXX],
[ if test yes != "$lt_cv_apple_cc_single_mod"; then
_LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
fi
],[])
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
])
# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
# ----------------------------------
# Links a minimal program and checks the executable
# for the system default hardcoded library path. In most cases,
# this is /usr/lib:/lib, but when the MPI compilers are used
# the location of the communication and MPI libs are included too.
# If we don't find anything, use the default library path according
# to the aix ld manual.
# Store the results from the different compilers for each TAGNAME.
# Allow to override them for all tags through lt_cv_aix_libpath.
m4_defun([_LT_SYS_MODULE_PATH_AIX],
[m4_require([_LT_DECL_SED])dnl
if test set = "${lt_cv_aix_libpath+set}"; then
aix_libpath=$lt_cv_aix_libpath
else
AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
[AC_LINK_IFELSE([AC_LANG_PROGRAM],[
lt_aix_libpath_sed='[
/Import File Strings/,/^$/ {
/^0/ {
s/^0 *\([^ ]*\) *$/\1/
p
}
}]'
_LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
# Check for a 64-bit object if we didn't find anything.
if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
_LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
fi],[])
if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
_LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
fi
])
aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
fi
])# _LT_SYS_MODULE_PATH_AIX
# _LT_SHELL_INIT(ARG)
# -------------------
m4_define([_LT_SHELL_INIT],
[m4_divert_text([M4SH-INIT], [$1
])])# _LT_SHELL_INIT
# _LT_PROG_ECHO_BACKSLASH
# -----------------------
# Find how we can fake an echo command that does not interpret backslash.
# In particular, with Autoconf 2.60 or later we add some code to the start
# of the generated configure script that will find a shell with a builtin
# printf (that we can use as an echo command).
m4_defun([_LT_PROG_ECHO_BACKSLASH],
[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
AC_MSG_CHECKING([how to print strings])
# Test print first, because it will be a builtin if present.
if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
ECHO='print -r --'
elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
ECHO='printf %s\n'
else
# Use this function as a fallback that always works.
func_fallback_echo ()
{
eval 'cat <<_LTECHO_EOF
$[]1
_LTECHO_EOF'
}
ECHO='func_fallback_echo'
fi
# func_echo_all arg...
# Invoke $ECHO with all args, space-separated.
func_echo_all ()
{
$ECHO "$*"
}
case $ECHO in
printf*) AC_MSG_RESULT([printf]) ;;
print*) AC_MSG_RESULT([print -r]) ;;
*) AC_MSG_RESULT([cat]) ;;
esac
m4_ifdef([_AS_DETECT_SUGGESTED],
[_AS_DETECT_SUGGESTED([
test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
PATH=/empty FPATH=/empty; export PATH FPATH
test "X`printf %s $ECHO`" = "X$ECHO" \
|| test "X`print -r -- $ECHO`" = "X$ECHO" )])])
_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
])# _LT_PROG_ECHO_BACKSLASH
# _LT_WITH_SYSROOT
# ----------------
AC_DEFUN([_LT_WITH_SYSROOT],
[AC_MSG_CHECKING([for sysroot])
AC_ARG_WITH([sysroot],
[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
[Search for dependent libraries within DIR (or the compiler's sysroot
if not specified).])],
[], [with_sysroot=no])
dnl lt_sysroot will always be passed unquoted. We quote it here
dnl in case the user passed a directory name.
lt_sysroot=
case $with_sysroot in #(
yes)
if test yes = "$GCC"; then
lt_sysroot=`$CC --print-sysroot 2>/dev/null`
fi
;; #(
/*)
lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
;; #(
no|'')
;; #(
*)
AC_MSG_RESULT([$with_sysroot])
AC_MSG_ERROR([The sysroot must be an absolute path.])
;;
esac
AC_MSG_RESULT([${lt_sysroot:-no}])
_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
[dependent libraries, and where our libraries should be installed.])])
# _LT_ENABLE_LOCK
# ---------------
m4_defun([_LT_ENABLE_LOCK],
[AC_ARG_ENABLE([libtool-lock],
[AS_HELP_STRING([--disable-libtool-lock],
[avoid locking (might break parallel builds)])])
test no = "$enable_libtool_lock" || enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
ia64-*-hpux*)
# Find out what ABI is being produced by ac_compile, and set mode
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*)
HPUX_IA64_MODE=32
;;
*ELF-64*)
HPUX_IA64_MODE=64
;;
esac
fi
rm -rf conftest*
;;
*-*-irix6*)
# Find out what ABI is being produced by ac_compile, and set linker
# options accordingly.
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
if test yes = "$lt_cv_prog_gnu_ld"; then
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
;;
*N32*)
LD="${LD-ld} -melf32bmipn32"
;;
*64-bit*)
LD="${LD-ld} -melf64bmip"
;;
esac
else
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -32"
;;
*N32*)
LD="${LD-ld} -n32"
;;
*64-bit*)
LD="${LD-ld} -64"
;;
esac
fi
fi
rm -rf conftest*
;;
mips64*-*linux*)
# Find out what ABI is being produced by ac_compile, and set linker
# options accordingly.
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
emul=elf
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
emul="${emul}32"
;;
*64-bit*)
emul="${emul}64"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
*MSB*)
emul="${emul}btsmip"
;;
*LSB*)
emul="${emul}ltsmip"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
*N32*)
emul="${emul}n32"
;;
esac
LD="${LD-ld} -m $emul"
fi
rm -rf conftest*
;;
x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out what ABI is being produced by ac_compile, and set linker
# options accordingly. Note that the listed cases only cover the
# situations where additional linker options are needed (such as when
# doing 32-bit compilation for a host where ld defaults to 64-bit, or
# vice versa); the common cases where no linker options are needed do
# not appear in the list.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
*32-bit*)
case $host in
x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
case `/usr/bin/file conftest.o` in
*x86-64*)
LD="${LD-ld} -m elf32_x86_64"
;;
*)
LD="${LD-ld} -m elf_i386"
;;
esac
;;
powerpc64le-*linux*)
LD="${LD-ld} -m elf32lppclinux"
;;
powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
LD="${LD-ld} -m elf_s390"
;;
sparc64-*linux*)
LD="${LD-ld} -m elf32_sparc"
;;
esac
;;
*64-bit*)
case $host in
x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_x86_64_fbsd"
;;
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
powerpcle-*linux*)
LD="${LD-ld} -m elf64lppc"
;;
powerpc-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
LD="${LD-ld} -m elf64_s390"
;;
sparc*-*linux*)
LD="${LD-ld} -m elf64_sparc"
;;
esac
;;
esac
fi
rm -rf conftest*
;;
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
SAVE_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -belf"
AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
[AC_LANG_PUSH(C)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
AC_LANG_POP])
if test yes != "$lt_cv_cc_needs_belf"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
CFLAGS=$SAVE_CFLAGS
fi
;;
*-*solaris*)
# Find out what ABI is being produced by ac_compile, and set linker
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
*64-bit*)
case $lt_cv_prog_gnu_ld in
yes*)
case $host in
i?86-*-solaris*|x86_64-*-solaris*)
LD="${LD-ld} -m elf_x86_64"
;;
sparc*-*-solaris*)
LD="${LD-ld} -m elf64_sparc"
;;
esac
# GNU ld 2.21 introduced _sol2 emulations. Use them if available.
if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
LD=${LD-ld}_sol2
fi
;;
*)
if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
LD="${LD-ld} -64"
fi
;;
esac
;;
esac
fi
rm -rf conftest*
;;
esac
need_locks=$enable_libtool_lock
])# _LT_ENABLE_LOCK
# _LT_PROG_AR
# -----------
m4_defun([_LT_PROG_AR],
[AC_CHECK_TOOLS(AR, [ar], false)
: ${AR=ar}
: ${AR_FLAGS=cru}
_LT_DECL([], [AR], [1], [The archiver])
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[lt_cv_ar_at_file=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
[echo conftest.$ac_objext > conftest.lst
lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
AC_TRY_EVAL([lt_ar_try])
if test 0 -eq "$ac_status"; then
# Ensure the archiver fails upon bogus file names.
rm -f conftest.$ac_objext libconftest.a
AC_TRY_EVAL([lt_ar_try])
if test 0 -ne "$ac_status"; then
lt_cv_ar_at_file=@
fi
fi
rm -f conftest.* libconftest.a
])
])
if test no = "$lt_cv_ar_at_file"; then
archiver_list_spec=
else
archiver_list_spec=$lt_cv_ar_at_file
fi
_LT_DECL([], [archiver_list_spec], [1],
[How to feed a file listing to the archiver])
])# _LT_PROG_AR
# _LT_CMD_OLD_ARCHIVE
# -------------------
m4_defun([_LT_CMD_OLD_ARCHIVE],
[_LT_PROG_AR
AC_CHECK_TOOL(STRIP, strip, :)
test -z "$STRIP" && STRIP=:
_LT_DECL([], [STRIP], [1], [A symbol stripping program])
AC_CHECK_TOOL(RANLIB, ranlib, :)
test -z "$RANLIB" && RANLIB=:
_LT_DECL([], [RANLIB], [1],
[Commands used to install an old-style archive])
# Determine commands to create old-style static archives.
old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
old_postinstall_cmds='chmod 644 $oldlib'
old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
bitrig* | openbsd*)
old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
;;
esac
old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
fi
case $host_os in
darwin*)
lock_old_archive_extraction=yes ;;
*)
lock_old_archive_extraction=no ;;
esac
_LT_DECL([], [old_postinstall_cmds], [2])
_LT_DECL([], [old_postuninstall_cmds], [2])
_LT_TAGDECL([], [old_archive_cmds], [2],
[Commands used to build an old-style archive])
_LT_DECL([], [lock_old_archive_extraction], [0],
[Whether to use a lock for old archive extraction])
])# _LT_CMD_OLD_ARCHIVE
# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
# ----------------------------------------------------------------
# Check whether the given compiler option works
AC_DEFUN([_LT_COMPILER_OPTION],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_SED])dnl
AC_CACHE_CHECK([$1], [$2],
[$2=no
m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&AS_MESSAGE_LOG_FD
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
$ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
$2=yes
fi
fi
$RM conftest*
])
if test yes = "[$]$2"; then
m4_if([$5], , :, [$5])
else
m4_if([$6], , :, [$6])
fi
])# _LT_COMPILER_OPTION
# Old name:
AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
# [ACTION-SUCCESS], [ACTION-FAILURE])
# ----------------------------------------------------
# Check whether the given linker option works
AC_DEFUN([_LT_LINKER_OPTION],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_SED])dnl
AC_CACHE_CHECK([$1], [$2],
[$2=no
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS $3"
echo "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
# The linker can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s conftest.err; then
# Append any errors to the config.log.
cat conftest.err 1>&AS_MESSAGE_LOG_FD
$ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
$SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
if diff conftest.exp conftest.er2 >/dev/null; then
$2=yes
fi
else
$2=yes
fi
fi
$RM -r conftest*
LDFLAGS=$save_LDFLAGS
])
if test yes = "[$]$2"; then
m4_if([$4], , :, [$4])
else
m4_if([$5], , :, [$5])
fi
])# _LT_LINKER_OPTION
# Old name:
AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
# LT_CMD_MAX_LEN
#---------------
AC_DEFUN([LT_CMD_MAX_LEN],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
# find the maximum length of command line arguments
AC_MSG_CHECKING([the maximum length of command line arguments])
AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
i=0
teststring=ABCD
case $build_os in
msdosdjgpp*)
# On DJGPP, this test can blow up pretty badly due to problems in libc
# (any single argument exceeding 2000 bytes causes a buffer overrun
# during glob expansion). Even if it were fixed, the result of this
# check would be larger than it should be.
lt_cv_sys_max_cmd_len=12288; # 12K is about right
;;
gnu*)
# Under GNU Hurd, this test is not required because there is
# no limit to the length of command line arguments.
# Libtool will interpret -1 as no limit whatsoever
lt_cv_sys_max_cmd_len=-1;
;;
cygwin* | mingw* | cegcc*)
# On Win9x/ME, this test blows up -- it succeeds, but takes
# about 5 minutes as the teststring grows exponentially.
# Worse, since 9x/ME are not pre-emptively multitasking,
# you end up with a "frozen" computer, even though with patience
# the test eventually succeeds (with a max line length of 256k).
# Instead, let's just punt: use the minimum linelength reported by
# all of the supported platforms: 8192 (on NT/2K/XP).
lt_cv_sys_max_cmd_len=8192;
;;
mint*)
# On MiNT this can take a long time and run out of memory.
lt_cv_sys_max_cmd_len=8192;
;;
amigaos*)
# On AmigaOS with pdksh, this test takes hours, literally.
# So we just punt and use a minimum line length of 8192.
lt_cv_sys_max_cmd_len=8192;
;;
bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
elif test -x /usr/sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
else
lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
fi
# And add a safety zone
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
;;
interix*)
# We know the value 262144 and hardcode it with a safety zone (like BSD)
lt_cv_sys_max_cmd_len=196608
;;
os2*)
# The test takes a long time on OS/2.
lt_cv_sys_max_cmd_len=8192
;;
osf*)
# Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
# due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
# nice to cause kernel panics so lets avoid the loop below.
# First set a reasonable default.
lt_cv_sys_max_cmd_len=16384
#
if test -x /sbin/sysconfig; then
case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
*1*) lt_cv_sys_max_cmd_len=-1 ;;
esac
fi
;;
sco3.2v5*)
lt_cv_sys_max_cmd_len=102400
;;
sysv5* | sco5v6* | sysv4.2uw2*)
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
if test -n "$kargmax"; then
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
else
lt_cv_sys_max_cmd_len=32768
fi
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
if test -n "$lt_cv_sys_max_cmd_len" && \
test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
# Make teststring a little bigger before we do anything with it.
# a 1K string should be a reasonable start.
for i in 1 2 3 4 5 6 7 8; do
teststring=$teststring$teststring
done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
while { test X`env echo "$teststring$teststring" 2>/dev/null` \
= "X$teststring$teststring"; } >/dev/null 2>&1 &&
test 17 != "$i" # 1/2 MB should be enough
do
i=`expr $i + 1`
teststring=$teststring$teststring
done
# Only check the string length outside the loop.
lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
teststring=
# Add a significant safety factor because C++ compilers can tack on
# massive amounts of additional arguments before passing them to the
# linker. It appears as though 1/2 is a usable value.
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
fi
;;
esac
])
if test -n "$lt_cv_sys_max_cmd_len"; then
AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
else
AC_MSG_RESULT(none)
fi
max_cmd_len=$lt_cv_sys_max_cmd_len
_LT_DECL([], [max_cmd_len], [0],
[What is the maximum length of a command?])
])# LT_CMD_MAX_LEN
# Old name:
AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
# _LT_HEADER_DLFCN
# ----------------
m4_defun([_LT_HEADER_DLFCN],
[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
])# _LT_HEADER_DLFCN
# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
# ----------------------------------------------------------------
m4_defun([_LT_TRY_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
if test yes = "$cross_compiling"; then :
[$4]
else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
[#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
#include
#endif
#include
#ifdef RTLD_GLOBAL
# define LT_DLGLOBAL RTLD_GLOBAL
#else
# ifdef DL_GLOBAL
# define LT_DLGLOBAL DL_GLOBAL
# else
# define LT_DLGLOBAL 0
# endif
#endif
/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
find out it does not work in some platform. */
#ifndef LT_DLLAZY_OR_NOW
# ifdef RTLD_LAZY
# define LT_DLLAZY_OR_NOW RTLD_LAZY
# else
# ifdef DL_LAZY
# define LT_DLLAZY_OR_NOW DL_LAZY
# else
# ifdef RTLD_NOW
# define LT_DLLAZY_OR_NOW RTLD_NOW
# else
# ifdef DL_NOW
# define LT_DLLAZY_OR_NOW DL_NOW
# else
# define LT_DLLAZY_OR_NOW 0
# endif
# endif
# endif
# endif
#endif
/* When -fvisibility=hidden is used, assume the code has been annotated
correspondingly for the symbols needed. */
#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
int fnord () __attribute__((visibility("default")));
#endif
int fnord () { return 42; }
int main ()
{
void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
int status = $lt_dlunknown;
if (self)
{
if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
else
{
if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
else puts (dlerror ());
}
/* dlclose (self); */
}
else
puts (dlerror ());
return status;
}]
_LT_EOF
if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
(./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) $1 ;;
x$lt_dlneed_uscore) $2 ;;
x$lt_dlunknown|x*) $3 ;;
esac
else :
# compilation failed
$3
fi
fi
rm -fr conftest*
])# _LT_TRY_DLOPEN_SELF
# LT_SYS_DLOPEN_SELF
# ------------------
AC_DEFUN([LT_SYS_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
if test yes != "$enable_dlopen"; then
enable_dlopen=unknown
enable_dlopen_self=unknown
enable_dlopen_self_static=unknown
else
lt_cv_dlopen=no
lt_cv_dlopen_libs=
case $host_os in
beos*)
lt_cv_dlopen=load_add_on
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
;;
mingw* | pw32* | cegcc*)
lt_cv_dlopen=LoadLibrary
lt_cv_dlopen_libs=
;;
cygwin*)
lt_cv_dlopen=dlopen
lt_cv_dlopen_libs=
;;
darwin*)
# if libdl is installed we need to link against it
AC_CHECK_LIB([dl], [dlopen],
[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
lt_cv_dlopen=dyld
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
])
;;
tpf*)
# Don't try to run any link tests for TPF. We know it's impossible
# because TPF is a cross-compiler, and we know how we open DSOs.
lt_cv_dlopen=dlopen
lt_cv_dlopen_libs=
lt_cv_dlopen_self=no
;;
*)
AC_CHECK_FUNC([shl_load],
[lt_cv_dlopen=shl_load],
[AC_CHECK_LIB([dld], [shl_load],
[lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
[AC_CHECK_FUNC([dlopen],
[lt_cv_dlopen=dlopen],
[AC_CHECK_LIB([dl], [dlopen],
[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
[AC_CHECK_LIB([svld], [dlopen],
[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
[AC_CHECK_LIB([dld], [dld_link],
[lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
])
])
])
])
])
;;
esac
if test no = "$lt_cv_dlopen"; then
enable_dlopen=no
else
enable_dlopen=yes
fi
case $lt_cv_dlopen in
dlopen)
save_CPPFLAGS=$CPPFLAGS
test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
save_LDFLAGS=$LDFLAGS
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
save_LIBS=$LIBS
LIBS="$lt_cv_dlopen_libs $LIBS"
AC_CACHE_CHECK([whether a program can dlopen itself],
lt_cv_dlopen_self, [dnl
_LT_TRY_DLOPEN_SELF(
lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
])
if test yes = "$lt_cv_dlopen_self"; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl
_LT_TRY_DLOPEN_SELF(
lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
])
fi
CPPFLAGS=$save_CPPFLAGS
LDFLAGS=$save_LDFLAGS
LIBS=$save_LIBS
;;
esac
case $lt_cv_dlopen_self in
yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
*) enable_dlopen_self=unknown ;;
esac
case $lt_cv_dlopen_self_static in
yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
*) enable_dlopen_self_static=unknown ;;
esac
fi
_LT_DECL([dlopen_support], [enable_dlopen], [0],
[Whether dlopen is supported])
_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
[Whether dlopen of programs is supported])
_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
[Whether dlopen of statically linked programs is supported])
])# LT_SYS_DLOPEN_SELF
# Old name:
AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
# _LT_COMPILER_C_O([TAGNAME])
# ---------------------------
# Check to see if options -c and -o are simultaneously supported by compiler.
# This macro does not hard code the compiler like AC_PROG_CC_C_O.
m4_defun([_LT_COMPILER_C_O],
[m4_require([_LT_DECL_SED])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_TAG_COMPILER])dnl
AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
[_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
[_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
$RM -r conftest 2>/dev/null
mkdir conftest
cd conftest
mkdir out
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&AS_MESSAGE_LOG_FD
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
$ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
$SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
fi
fi
chmod u+w . 2>&AS_MESSAGE_LOG_FD
$RM conftest*
# SGI C++ compiler will create directory out/ii_files/ for
# template instantiation
test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
$RM out/* && rmdir out
cd ..
$RM -r conftest
$RM conftest*
])
_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
[Does compiler simultaneously support -c and -o options?])
])# _LT_COMPILER_C_O
# _LT_COMPILER_FILE_LOCKS([TAGNAME])
# ----------------------------------
# Check to see if we can do hard links to lock some files if needed
m4_defun([_LT_COMPILER_FILE_LOCKS],
[m4_require([_LT_ENABLE_LOCK])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
_LT_COMPILER_C_O([$1])
hard_links=nottested
if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
# do not overwrite the value of need_locks provided by the user
AC_MSG_CHECKING([if we can lock with hard links])
hard_links=yes
$RM conftest*
ln conftest.a conftest.b 2>/dev/null && hard_links=no
touch conftest.a
ln conftest.a conftest.b 2>&5 || hard_links=no
ln conftest.a conftest.b 2>/dev/null && hard_links=no
AC_MSG_RESULT([$hard_links])
if test no = "$hard_links"; then
AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
need_locks=warn
fi
else
need_locks=no
fi
_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
])# _LT_COMPILER_FILE_LOCKS
# _LT_CHECK_OBJDIR
# ----------------
m4_defun([_LT_CHECK_OBJDIR],
[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
[rm -f .libs 2>/dev/null
mkdir .libs 2>/dev/null
if test -d .libs; then
lt_cv_objdir=.libs
else
# MS-DOS does not allow filenames that begin with a dot.
lt_cv_objdir=_libs
fi
rmdir .libs 2>/dev/null])
objdir=$lt_cv_objdir
_LT_DECL([], [objdir], [0],
[The name of the directory that contains temporary libtool files])dnl
m4_pattern_allow([LT_OBJDIR])dnl
AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
[Define to the sub-directory where libtool stores uninstalled libraries.])
])# _LT_CHECK_OBJDIR
# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
# --------------------------------------
# Check hardcoding attributes.
m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
[AC_MSG_CHECKING([how to hardcode library paths into programs])
_LT_TAGVAR(hardcode_action, $1)=
if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
test -n "$_LT_TAGVAR(runpath_var, $1)" ||
test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
# We can hardcode non-existent directories.
if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
# when we should be linking with a yet-to-be-installed one
## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
# Linking always hardcodes the temporary library directory.
_LT_TAGVAR(hardcode_action, $1)=relink
else
# We can link without hardcoding, and we can hardcode nonexisting dirs.
_LT_TAGVAR(hardcode_action, $1)=immediate
fi
else
# We cannot hardcode anything, or else we can only hardcode existing
# directories.
_LT_TAGVAR(hardcode_action, $1)=unsupported
fi
AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
# Fast installation is not supported
enable_fast_install=no
elif test yes = "$shlibpath_overrides_runpath" ||
test no = "$enable_shared"; then
# Fast installation is not necessary
enable_fast_install=needless
fi
_LT_TAGDECL([], [hardcode_action], [0],
[How to hardcode a shared library path into an executable])
])# _LT_LINKER_HARDCODE_LIBPATH
# _LT_CMD_STRIPLIB
# ----------------
m4_defun([_LT_CMD_STRIPLIB],
[m4_require([_LT_DECL_EGREP])
striplib=
old_striplib=
AC_MSG_CHECKING([whether stripping libraries is possible])
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
if test -n "$STRIP"; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
;;
*)
AC_MSG_RESULT([no])
;;
esac
fi
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
_LT_DECL([], [striplib], [1])
])# _LT_CMD_STRIPLIB
# _LT_PREPARE_MUNGE_PATH_LIST
# ---------------------------
# Make sure func_munge_path_list() is defined correctly.
m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
[[# func_munge_path_list VARIABLE PATH
# -----------------------------------
# VARIABLE is name of variable containing _space_ separated list of
# directories to be munged by the contents of PATH, which is string
# having a format:
# "DIR[:DIR]:"
# string "DIR[ DIR]" will be prepended to VARIABLE
# ":DIR[:DIR]"
# string "DIR[ DIR]" will be appended to VARIABLE
# "DIRP[:DIRP]::[DIRA:]DIRA"
# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
# "DIRA[ DIRA]" will be appended to VARIABLE
# "DIR[:DIR]"
# VARIABLE will be replaced by "DIR[ DIR]"
func_munge_path_list ()
{
case x@S|@2 in
x)
;;
*:)
eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
;;
x:*)
eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
;;
*::*)
eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
;;
*)
eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
;;
esac
}
]])# _LT_PREPARE_PATH_LIST
# _LT_SYS_DYNAMIC_LINKER([TAG])
# -----------------------------
# PORTME Fill in your ld.so characteristics
m4_defun([_LT_SYS_DYNAMIC_LINKER],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_OBJDUMP])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
AC_MSG_CHECKING([dynamic linker characteristics])
m4_if([$1],
[], [
if test yes = "$GCC"; then
case $host_os in
darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
*) lt_awk_arg='/^libraries:/' ;;
esac
case $host_os in
mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
*) lt_sed_strip_eq='s|=/|/|g' ;;
esac
lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
case $lt_search_path_spec in
*\;*)
# if the path contains ";" then we assume it to be the separator
# otherwise default to the standard path separator (i.e. ":") - it is
# assumed that no part of a normal pathname contains ";" but that should
# okay in the real world where ";" in dirpaths is itself problematic.
lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
;;
*)
lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
;;
esac
# Ok, now we have the path, separated by spaces, we can step through it
# and add multilib dir if necessary...
lt_tmp_lt_search_path_spec=
lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
# ...but if some path component already ends with the multilib dir we assume
# that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
case "$lt_multi_os_dir; $lt_search_path_spec " in
"/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
lt_multi_os_dir=
;;
esac
for lt_sys_path in $lt_search_path_spec; do
if test -d "$lt_sys_path$lt_multi_os_dir"; then
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
elif test -n "$lt_multi_os_dir"; then
test -d "$lt_sys_path" && \
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
BEGIN {RS = " "; FS = "/|\n";} {
lt_foo = "";
lt_count = 0;
for (lt_i = NF; lt_i > 0; lt_i--) {
if ($lt_i != "" && $lt_i != ".") {
if ($lt_i == "..") {
lt_count++;
} else {
if (lt_count == 0) {
lt_foo = "/" $lt_i lt_foo;
} else {
lt_count--;
}
}
}
}
if (lt_foo != "") { lt_freq[[lt_foo]]++; }
if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
}'`
# AWK program above erroneously prepends '/' to C:/dos/paths
# for these hosts.
case $host_os in
mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
$SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
esac
sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
fi])
library_names_spec=
libname_spec='lib$name'
soname_spec=
shrext_cmds=.so
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
finish_eval=
shlibpath_var=
shlibpath_overrides_runpath=unknown
version_type=none
dynamic_linker="$host_os ld.so"
sys_lib_dlsearch_path_spec="/lib /usr/lib"
need_lib_prefix=unknown
hardcode_into_libs=no
# when you set need_version to no, make sure it does not cause -set_version
# flags to be left without arguments
need_version=unknown
AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
[User-defined run-time library search path.])
case $host_os in
aix3*)
version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
shlibpath_var=LIBPATH
# AIX 3 has no versioning support, so we append a major version to the name.
soname_spec='$libname$release$shared_ext$major'
;;
aix[[4-9]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
if test ia64 = "$host_cpu"; then
# AIX 5 supports IA64
library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
# the line '#! .'. This would cause the generated library to
# depend on '.', always an invalid library. This was fixed in
# development snapshots of GCC prior to 3.0.
case $host_os in
aix4 | aix4.[[01]] | aix4.[[01]].*)
if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
echo ' yes '
echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
:
else
can_build_shared=no
fi
;;
esac
# Using Import Files as archive members, it is possible to support
# filename-based versioning of shared library archives on AIX. While
# this would work for both with and without runtime linking, it will
# prevent static linking of such archives. So we do filename-based
# shared library versioning with .so extension only, which is used
# when both runtime linking and shared linking is enabled.
# Unfortunately, runtime linking may impact performance, so we do
# not want this to be the default eventually. Also, we use the
# versioned .so libs for executables only if there is the -brtl
# linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
# To allow for filename-based versioning support, we need to create
# libNAME.so.V as an archive file, containing:
# *) an Import File, referring to the versioned filename of the
# archive as well as the shared archive member, telling the
# bitwidth (32 or 64) of that shared object, and providing the
# list of exported symbols of that shared object, eventually
# decorated with the 'weak' keyword
# *) the shared object with the F_LOADONLY flag set, to really avoid
# it being seen by the linker.
# At run time we better use the real file rather than another symlink,
# but for link time we create the symlink libNAME.so -> libNAME.so.V
case $with_aix_soname,$aix_use_runtimelinking in
# AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
# soname into executable. Probably we can add versioning support to
# collect2, so additional links can be useful in future.
aix,yes) # traditional libtool
dynamic_linker='AIX unversionable lib.so'
# If using run time linking (on AIX 4.2 or later) use lib.so
# instead of lib.a to let people know that these are not
# typical AIX shared libraries.
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
;;
aix,no) # traditional AIX only
dynamic_linker='AIX lib.a[(]lib.so.V[)]'
# We preserve .a as extension for shared libraries through AIX4.2
# and later when we are not doing run time linking.
library_names_spec='$libname$release.a $libname.a'
soname_spec='$libname$release$shared_ext$major'
;;
svr4,*) # full svr4 only
dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
# We do not specify a path in Import Files, so LIBPATH fires.
shlibpath_overrides_runpath=yes
;;
*,yes) # both, prefer svr4
dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
# unpreferred sharedlib libNAME.a needs extra handling
postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
# We do not specify a path in Import Files, so LIBPATH fires.
shlibpath_overrides_runpath=yes
;;
*,no) # both, prefer aix
dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
library_names_spec='$libname$release.a $libname.a'
soname_spec='$libname$release$shared_ext$major'
# unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
;;
esac
shlibpath_var=LIBPATH
fi
;;
amigaos*)
case $host_cpu in
powerpc)
# Since July 2007 AmigaOS4 officially supports .so libraries.
# When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
;;
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
beos*)
library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"
shlibpath_var=LIBRARY_PATH
;;
bsdi[[45]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
# the default ld.so.conf also contains /usr/contrib/lib and
# /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
# libtool to hard-code these into programs
;;
cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
shrext_cmds=.dll
need_version=no
need_lib_prefix=no
case $GCC,$cc_basename in
yes,*)
# gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \$file`~
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~
chmod a+x \$dldir/$dlname~
if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
fi'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$RM \$dlpath'
shlibpath_overrides_runpath=yes
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
esac
dynamic_linker='Win32 ld.exe'
;;
*,cl*)
# Native MSVC
libname_spec='$name'
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='$libname.dll.lib'
case $build_os in
mingw*)
sys_lib_search_path_spec=
lt_save_ifs=$IFS
IFS=';'
for lt_path in $LIB
do
IFS=$lt_save_ifs
# Let DOS variable expansion print the short 8.3 style file name.
lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
done
IFS=$lt_save_ifs
# Convert to MSYS style.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
;;
cygwin*)
# Convert to unix form, then to dos form, then back to unix form
# but this time dos style (no spaces!) so that the unix form looks
# like /cygdrive/c/PROGRA~1:/cygdr...
sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
;;
*)
sys_lib_search_path_spec=$LIB
if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
# It is most probably a Windows format PATH.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
else
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
fi
# FIXME: find the short name or the path components, as spaces are
# common. (e.g. "Program Files" -> "PROGRA~1")
;;
esac
# DLL is installed to $(libdir)/../bin by postinstall_cmds
postinstall_cmds='base_file=`basename \$file`~
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$RM \$dlpath'
shlibpath_overrides_runpath=yes
dynamic_linker='Win32 link.exe'
;;
*)
# Assume MSVC wrapper
library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
esac
# FIXME: first we should search . and the directory the executable is in
shlibpath_var=PATH
;;
darwin* | rhapsody*)
dynamic_linker="$host_os dyld"
version_type=darwin
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
soname_spec='$libname$release$major$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
dgux*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
;;
freebsd* | dragonfly*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
if test -x /usr/bin/objformat; then
objformat=`/usr/bin/objformat`
else
case $host_os in
freebsd[[23]].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
need_version=no
need_lib_prefix=no
;;
freebsd-*)
library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
need_version=yes
;;
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[[01]]* | freebsdelf3.[[01]]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
*) # from 4.6 on, and DragonFly
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
esac
;;
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
dynamic_linker="$host_os runtime_loader"
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LIBRARY_PATH
shlibpath_overrides_runpath=no
sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
hpux9* | hpux10* | hpux11*)
# Give a soname corresponding to the major version so that dld.sl refuses to
# link against other versions.
version_type=sunos
need_lib_prefix=no
need_version=no
case $host_cpu in
ia64*)
shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
if test 32 = "$HPUX_IA64_MODE"; then
sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
sys_lib_dlsearch_path_spec=/usr/lib/hpux32
else
sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
sys_lib_dlsearch_path_spec=/usr/lib/hpux64
fi
;;
hppa*64*)
shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
;;
esac
# HP-UX runs *really* slowly unless shared libraries are mode 555, ...
postinstall_cmds='chmod 555 $lib'
# or fails outright, so override atomically:
install_override_mode=555
;;
interix[[3-9]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
*)
if test yes = "$lt_cv_prog_gnu_ld"; then
version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
fi ;;
esac
need_lib_prefix=no
need_version=no
soname_spec='$libname$release$shared_ext$major'
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
case $host_os in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in # libtool.m4 will add one of these switches to LD
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
libsuff= shlibsuff= libmagic=32-bit;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
libsuff=32 shlibsuff=N32 libmagic=N32;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
libsuff=64 shlibsuff=64 libmagic=64-bit;;
*) libsuff= shlibsuff= libmagic=never-match;;
esac
;;
esac
shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
shlibpath_overrides_runpath=no
sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
hardcode_into_libs=yes
;;
# No shared lib support for Linux oldld, aout, or coff.
linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
linux*android*)
version_type=none # Android doesn't support versioned libraries.
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext'
soname_spec='$libname$release$shared_ext'
finish_cmds=
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
# This implies no fast_install, which is unacceptable.
# Some rework will be needed to allow for fast_install
# before this can be enabled.
hardcode_into_libs=yes
dynamic_linker='Android linker'
# Don't embed -rpath directories since the linker doesn't support them.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
;;
# This must be glibc/ELF.
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
# Some binutils ld are patched to set DT_RUNPATH
AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
[lt_cv_shlibpath_overrides_runpath=no
save_LDFLAGS=$LDFLAGS
save_libdir=$libdir
eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
[AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
[lt_cv_shlibpath_overrides_runpath=yes])])
LDFLAGS=$save_LDFLAGS
libdir=$save_libdir
])
shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
# This implies no fast_install, which is unacceptable.
# Some rework will be needed to allow for fast_install
# before this can be enabled.
hardcode_into_libs=yes
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
# 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
# even though it is searched at run-time. Try to do the best guess by
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
# most powerpc-linux boxes support dynamic linking these days and
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
;;
netbsd*)
version_type=sunos
need_lib_prefix=no
need_version=no
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
dynamic_linker='NetBSD ld.elf_so'
fi
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
newsos6)
version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
;;
*nto* | *qnx*)
version_type=qnx
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='ldqnx.so'
;;
openbsd* | bitrig*)
version_type=sunos
sys_lib_dlsearch_path_spec=/usr/lib
need_lib_prefix=no
if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
need_version=no
else
need_version=yes
fi
library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
;;
os2*)
libname_spec='$name'
version_type=windows
shrext_cmds=.dll
need_version=no
need_lib_prefix=no
# OS/2 can only load a DLL with a base name of 8 characters or less.
soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
v=$($ECHO $release$versuffix | tr -d .-);
n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
$ECHO $n$v`$shared_ext'
library_names_spec='${libname}_dll.$libext'
dynamic_linker='OS/2 ld.exe'
shlibpath_var=BEGINLIBPATH
sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
postinstall_cmds='base_file=`basename \$file`~
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~
chmod a+x \$dldir/$dlname~
if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
fi'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
dlpath=$dir/\$dldll~
$RM \$dlpath'
;;
osf3* | osf4* | osf5*)
version_type=osf
need_lib_prefix=no
need_version=no
soname_spec='$libname$release$shared_ext$major'
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
rdos*)
dynamic_linker=no
;;
solaris*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
# ldd complains unless libraries are executable
postinstall_cmds='chmod +x $lib'
;;
sunos4*)
version_type=sunos
library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
if test yes = "$with_gnu_ld"; then
need_lib_prefix=no
fi
need_version=yes
;;
sysv4 | sysv4.3*)
version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
case $host_vendor in
sni)
shlibpath_overrides_runpath=no
need_lib_prefix=no
runpath_var=LD_RUN_PATH
;;
siemens)
need_lib_prefix=no
;;
motorola)
need_lib_prefix=no
need_version=no
shlibpath_overrides_runpath=no
sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
;;
esac
;;
sysv4*MP*)
if test -d /usr/nec; then
version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
soname_spec='$libname$shared_ext.$major'
shlibpath_var=LD_LIBRARY_PATH
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
version_type=sco
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
if test yes = "$with_gnu_ld"; then
sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
else
sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
case $host_os in
sco3.2v5*)
sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
;;
esac
fi
sys_lib_dlsearch_path_spec='/usr/lib'
;;
tpf*)
# TPF is a cross-target only. Preferred cross-host = GNU/Linux.
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
uts4*)
version_type=linux # correct to gnu/linux during the next big refactor
library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
;;
*)
dynamic_linker=no
;;
esac
AC_MSG_RESULT([$dynamic_linker])
test no = "$dynamic_linker" && can_build_shared=no
variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
if test yes = "$GCC"; then
variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
fi
if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
fi
# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
_LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and
restored at link time])
_LT_DECL([], [need_lib_prefix], [0],
[Do we need the "lib" prefix for modules?])
_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
_LT_DECL([], [version_type], [0], [Library versioning type])
_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
_LT_DECL([], [shlibpath_overrides_runpath], [0],
[Is shlibpath searched before the hard-coded library search path?])
_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
_LT_DECL([], [library_names_spec], [1],
[[List of archive names. First name is the real one, the rest are links.
The last name is the one that the linker finds with -lNAME]])
_LT_DECL([], [soname_spec], [1],
[[The coded name of the library, if different from the real name]])
_LT_DECL([], [install_override_mode], [1],
[Permission mode override for installation of shared libraries])
_LT_DECL([], [postinstall_cmds], [2],
[Command to use after installation of a shared archive])
_LT_DECL([], [postuninstall_cmds], [2],
[Command to use after uninstallation of a shared archive])
_LT_DECL([], [finish_cmds], [2],
[Commands used to finish a libtool library installation in a directory])
_LT_DECL([], [finish_eval], [1],
[[As "finish_cmds", except a single script fragment to be evaled but
not shown]])
_LT_DECL([], [hardcode_into_libs], [0],
[Whether we should hardcode library paths into libraries])
_LT_DECL([], [sys_lib_search_path_spec], [2],
[Compile-time system search path for libraries])
_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
[Detected run-time system search path for libraries])
_LT_DECL([], [configure_time_lt_sys_library_path], [2],
[Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
])# _LT_SYS_DYNAMIC_LINKER
# _LT_PATH_TOOL_PREFIX(TOOL)
# --------------------------
# find a file program that can recognize shared library
AC_DEFUN([_LT_PATH_TOOL_PREFIX],
[m4_require([_LT_DECL_EGREP])dnl
AC_MSG_CHECKING([for $1])
AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
[case $MAGIC_CMD in
[[\\/*] | ?:[\\/]*])
lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
;;
*)
lt_save_MAGIC_CMD=$MAGIC_CMD
lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
dnl $ac_dummy forces splitting on constant user-supplied paths.
dnl POSIX.2 word splitting is done only on the output of word expansions,
dnl not every word. This closes a longstanding sh security hole.
ac_dummy="m4_if([$2], , $PATH, [$2])"
for ac_dir in $ac_dummy; do
IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$1"; then
lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
MAGIC_CMD=$lt_cv_path_MAGIC_CMD
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
:
else
cat <<_LT_EOF 1>&2
*** Warning: the command libtool uses to detect shared libraries,
*** $file_magic_cmd, produces output that libtool cannot recognize.
*** The result is that libtool may fail to recognize shared libraries
*** as such. This will affect the creation of libtool libraries that
*** depend on shared libraries, but programs linked with such libtool
*** libraries will work regardless of this problem. Nevertheless, you
*** may want to report the problem to your system manager and/or to
*** bug-libtool@gnu.org
_LT_EOF
fi ;;
esac
fi
break
fi
done
IFS=$lt_save_ifs
MAGIC_CMD=$lt_save_MAGIC_CMD
;;
esac])
MAGIC_CMD=$lt_cv_path_MAGIC_CMD
if test -n "$MAGIC_CMD"; then
AC_MSG_RESULT($MAGIC_CMD)
else
AC_MSG_RESULT(no)
fi
_LT_DECL([], [MAGIC_CMD], [0],
[Used to examine libraries when file_magic_cmd begins with "file"])dnl
])# _LT_PATH_TOOL_PREFIX
# Old name:
AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
# _LT_PATH_MAGIC
# --------------
# find a file program that can recognize a shared library
m4_defun([_LT_PATH_MAGIC],
[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
if test -z "$lt_cv_path_MAGIC_CMD"; then
if test -n "$ac_tool_prefix"; then
_LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
else
MAGIC_CMD=:
fi
fi
])# _LT_PATH_MAGIC
# LT_PATH_LD
# ----------
# find the pathname to the GNU or non-GNU linker
AC_DEFUN([LT_PATH_LD],
[AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
AC_ARG_WITH([gnu-ld],
[AS_HELP_STRING([--with-gnu-ld],
[assume the C compiler uses GNU ld @<:@default=no@:>@])],
[test no = "$withval" || with_gnu_ld=yes],
[with_gnu_ld=no])dnl
ac_prog=ld
if test yes = "$GCC"; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by $CC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return, which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case $ac_prog in
# Accept absolute paths.
[[\\/]]* | ?:[[\\/]]*)
re_direlt='/[[^/]][[^/]]*/\.\./'
# Canonicalize the pathname of ld
ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
done
test -z "$LD" && LD=$ac_prog
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test yes = "$with_gnu_ld"; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(lt_cv_path_LD,
[if test -z "$LD"; then
lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD=$ac_dir/$ac_prog
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i
cat conftest.i conftest.i >conftest2.i
: ${lt_DD:=$DD}
AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then
cmp -s conftest.i conftest.out \
&& ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
fi])
rm -f conftest.i conftest2.i conftest.out])
])# _LT_PATH_DD
# _LT_CMD_TRUNCATE
# ----------------
# find command to truncate a binary pipe
m4_defun([_LT_CMD_TRUNCATE],
[m4_require([_LT_PATH_DD])
AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
[printf 0123456789abcdef0123456789abcdef >conftest.i
cat conftest.i conftest.i >conftest2.i
lt_cv_truncate_bin=
if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then
cmp -s conftest.i conftest.out \
&& lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
fi
rm -f conftest.i conftest2.i conftest.out
test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
[Command to truncate a binary pipe])
])# _LT_CMD_TRUNCATE
# _LT_CHECK_MAGIC_METHOD
# ----------------------
# how to check for library dependencies
# -- PORTME fill in with the dynamic library characteristics
m4_defun([_LT_CHECK_MAGIC_METHOD],
[m4_require([_LT_DECL_EGREP])
m4_require([_LT_DECL_OBJDUMP])
AC_CACHE_CHECK([how to recognize dependent libraries],
lt_cv_deplibs_check_method,
[lt_cv_file_magic_cmd='$MAGIC_CMD'
lt_cv_file_magic_test_file=
lt_cv_deplibs_check_method='unknown'
# Need to set the preceding variable on all platforms that support
# interlibrary dependencies.
# 'none' -- dependencies not supported.
# 'unknown' -- same as none, but documents that we really don't know.
# 'pass_all' -- all dependencies passed with no checks.
# 'test_compile' -- check by making test program.
# 'file_magic [[regex]]' -- check by looking for files in library path
# that responds to the $file_magic_cmd with a given extended regex.
# If you have 'file' or equivalent on your system and you're not sure
# whether 'pass_all' will *always* work, you probably want this one.
case $host_os in
aix[[4-9]]*)
lt_cv_deplibs_check_method=pass_all
;;
beos*)
lt_cv_deplibs_check_method=pass_all
;;
bsdi[[45]]*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
cygwin*)
# func_win32_libid is a shell function defined in ltmain.sh
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
;;
mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
if ( file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
# Keep this pattern in sync with the one in func_win32_libid.
lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
lt_cv_file_magic_cmd='$OBJDUMP -f'
fi
;;
cegcc*)
# use the weaker test based on 'objdump'. See mingw*.
lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
lt_cv_file_magic_cmd='$OBJDUMP -f'
;;
darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
freebsd* | dragonfly*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
esac
else
lt_cv_deplibs_check_method=pass_all
fi
;;
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
;;
hppa*64*)
[lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
;;
*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
esac
;;
interix[[3-9]]*)
# PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
;;
irix5* | irix6* | nonstopux*)
case $LD in
*-32|*"-32 ") libmagic=32-bit;;
*-n32|*"-n32 ") libmagic=N32;;
*-64|*"-64 ") libmagic=64-bit;;
*) libmagic=never-match;;
esac
lt_cv_deplibs_check_method=pass_all
;;
# This must be glibc/ELF.
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
fi
;;
newos6*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
*nto* | *qnx*)
lt_cv_deplibs_check_method=pass_all
;;
openbsd* | bitrig*)
if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
else
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
fi
;;
osf3* | osf4* | osf5*)
lt_cv_deplibs_check_method=pass_all
;;
rdos*)
lt_cv_deplibs_check_method=pass_all
;;
solaris*)
lt_cv_deplibs_check_method=pass_all
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
lt_cv_deplibs_check_method=pass_all
;;
sysv4 | sysv4.3*)
case $host_vendor in
motorola)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
;;
ncr)
lt_cv_deplibs_check_method=pass_all
;;
sequent)
lt_cv_file_magic_cmd='/bin/file'
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
;;
sni)
lt_cv_file_magic_cmd='/bin/file'
lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
lt_cv_file_magic_test_file=/lib/libc.so
;;
siemens)
lt_cv_deplibs_check_method=pass_all
;;
pc)
lt_cv_deplibs_check_method=pass_all
;;
esac
;;
tpf*)
lt_cv_deplibs_check_method=pass_all
;;
os2*)
lt_cv_deplibs_check_method=pass_all
;;
esac
])
file_magic_glob=
want_nocaseglob=no
if test "$build" = "$host"; then
case $host_os in
mingw* | pw32*)
if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
want_nocaseglob=yes
else
file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
fi
;;
esac
fi
file_magic_cmd=$lt_cv_file_magic_cmd
deplibs_check_method=$lt_cv_deplibs_check_method
test -z "$deplibs_check_method" && deplibs_check_method=unknown
_LT_DECL([], [deplibs_check_method], [1],
[Method to check whether dependent libraries are shared objects])
_LT_DECL([], [file_magic_cmd], [1],
[Command to use when deplibs_check_method = "file_magic"])
_LT_DECL([], [file_magic_glob], [1],
[How to find potential files when deplibs_check_method = "file_magic"])
_LT_DECL([], [want_nocaseglob], [1],
[Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
])# _LT_CHECK_MAGIC_METHOD
# LT_PATH_NM
# ----------
# find the pathname to a BSD- or MS-compatible name lister
AC_DEFUN([LT_PATH_NM],
[AC_REQUIRE([AC_PROG_CC])dnl
AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
lt_cv_path_NM=$NM
else
lt_nm_to_check=${ac_tool_prefix}nm
if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
lt_nm_to_check="$lt_nm_to_check nm"
fi
for lt_tmp_nm in $lt_nm_to_check; do
lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
tmp_nm=$ac_dir/$lt_tmp_nm
if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
# Check to see if the nm accepts a BSD-compat flag.
# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
# Tru64's nm complains that /dev/null is an invalid object file
# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
case $build_os in
mingw*) lt_bad_file=conftest.nm/nofile ;;
*) lt_bad_file=/dev/null ;;
esac
case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
*$lt_bad_file* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
break 2
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
break 2
;;
*)
lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
continue # so that we can try to find one that supports BSD flags
;;
esac
;;
esac
fi
done
IFS=$lt_save_ifs
done
: ${lt_cv_path_NM=no}
fi])
if test no != "$lt_cv_path_NM"; then
NM=$lt_cv_path_NM
else
# Didn't find any BSD compatible name lister, look for dumpbin.
if test -n "$DUMPBIN"; then :
# Let the user override the test.
else
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
*COFF*)
DUMPBIN="$DUMPBIN -symbols -headers"
;;
*)
DUMPBIN=:
;;
esac
fi
AC_SUBST([DUMPBIN])
if test : != "$DUMPBIN"; then
NM=$DUMPBIN
fi
fi
test -z "$NM" && NM=nm
AC_SUBST([NM])
_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
[lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&AS_MESSAGE_LOG_FD
(eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&AS_MESSAGE_LOG_FD
(eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
cat conftest.out >&AS_MESSAGE_LOG_FD
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
fi
rm -f conftest*])
])# LT_PATH_NM
# Old names:
AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_PROG_NM], [])
dnl AC_DEFUN([AC_PROG_NM], [])
# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
# --------------------------------
# how to determine the name of the shared library
# associated with a specific link library.
# -- PORTME fill in with the dynamic library characteristics
m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
[m4_require([_LT_DECL_EGREP])
m4_require([_LT_DECL_OBJDUMP])
m4_require([_LT_DECL_DLLTOOL])
AC_CACHE_CHECK([how to associate runtime and link libraries],
lt_cv_sharedlib_from_linklib_cmd,
[lt_cv_sharedlib_from_linklib_cmd='unknown'
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
# two different shell functions defined in ltmain.sh;
# decide which one to use based on capabilities of $DLLTOOL
case `$DLLTOOL --help 2>&1` in
*--identify-strict*)
lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
;;
*)
lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
;;
esac
;;
*)
# fallback: assume linklib IS sharedlib
lt_cv_sharedlib_from_linklib_cmd=$ECHO
;;
esac
])
sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
[Command to associate shared and link libraries])
])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
# _LT_PATH_MANIFEST_TOOL
# ----------------------
# locate the manifest tool
m4_defun([_LT_PATH_MANIFEST_TOOL],
[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
[lt_cv_path_mainfest_tool=no
echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
$MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
cat conftest.err >&AS_MESSAGE_LOG_FD
if $GREP 'Manifest Tool' conftest.out > /dev/null; then
lt_cv_path_mainfest_tool=yes
fi
rm -f conftest*])
if test yes != "$lt_cv_path_mainfest_tool"; then
MANIFEST_TOOL=:
fi
_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
])# _LT_PATH_MANIFEST_TOOL
# _LT_DLL_DEF_P([FILE])
# ---------------------
# True iff FILE is a Windows DLL '.def' file.
# Keep in sync with func_dll_def_p in the libtool script
AC_DEFUN([_LT_DLL_DEF_P],
[dnl
test DEF = "`$SED -n dnl
-e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
-e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
-e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
-e q dnl Only consider the first "real" line
$1`" dnl
])# _LT_DLL_DEF_P
# LT_LIB_M
# --------
# check for math library
AC_DEFUN([LT_LIB_M],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
LIBM=
case $host in
*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
# These system don't have libm, or don't need it
;;
*-ncr-sysv4.3*)
AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
;;
*)
AC_CHECK_LIB(m, cos, LIBM=-lm)
;;
esac
AC_SUBST([LIBM])
])# LT_LIB_M
# Old name:
AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_CHECK_LIBM], [])
# _LT_COMPILER_NO_RTTI([TAGNAME])
# -------------------------------
m4_defun([_LT_COMPILER_NO_RTTI],
[m4_require([_LT_TAG_COMPILER])dnl
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
if test yes = "$GCC"; then
case $cc_basename in
nvcc*)
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
*)
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
esac
_LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
lt_cv_prog_compiler_rtti_exceptions,
[-fno-rtti -fno-exceptions], [],
[_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
fi
_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
[Compiler flag to turn off builtin functions])
])# _LT_COMPILER_NO_RTTI
# _LT_CMD_GLOBAL_SYMBOLS
# ----------------------
m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([LT_PATH_NM])dnl
AC_REQUIRE([LT_PATH_LD])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_TAG_COMPILER])dnl
# Check for command to grab the raw symbol name followed by C symbol from nm.
AC_MSG_CHECKING([command to parse $NM output from $compiler object])
AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
[
# These are sane defaults that work on at least a few old systems.
# [They come from Ultrix. What could be older than Ultrix?!! ;)]
# Character class describing NM global symbol codes.
symcode='[[BCDEGRST]]'
# Regexp to match symbols that can be accessed directly from C.
sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
# Define system-specific variables.
case $host_os in
aix*)
symcode='[[BCDT]]'
;;
cygwin* | mingw* | pw32* | cegcc*)
symcode='[[ABCDGISTW]]'
;;
hpux*)
if test ia64 = "$host_cpu"; then
symcode='[[ABCDEGRST]]'
fi
;;
irix* | nonstopux*)
symcode='[[BCDEGRST]]'
;;
osf*)
symcode='[[BCDEGQRST]]'
;;
solaris*)
symcode='[[BDRT]]'
;;
sco3.2v5*)
symcode='[[DT]]'
;;
sysv4.2uw2*)
symcode='[[DT]]'
;;
sysv5* | sco5v6* | unixware* | OpenUNIX*)
symcode='[[ABDT]]'
;;
sysv4)
symcode='[[DFNSTU]]'
;;
esac
# If we're using GNU nm, then use its standard symbol codes.
case `$NM -V 2>&1` in
*GNU* | *'with BFD'*)
symcode='[[ABCDGIRSTW]]' ;;
esac
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Gets list of data symbols to import.
lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
# Adjust the below global symbol transforms to fixup imported variables.
lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
lt_c_name_lib_hook="\
-e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
-e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
else
# Disable hooks by default.
lt_cv_sys_global_symbol_to_import=
lt_cdecl_hook=
lt_c_name_hook=
lt_c_name_lib_hook=
fi
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
lt_cv_sys_global_symbol_to_cdecl="sed -n"\
$lt_cdecl_hook\
" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
$lt_c_name_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
# Transform an extracted symbol line into symbol name with lib prefix and
# symbol address.
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
$lt_c_name_lib_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
case $build_os in
mingw*)
opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
;;
esac
# Try without a prefix underscore, then with it.
for ac_symprfx in "" "_"; do
# Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
symxfrm="\\1 $ac_symprfx\\2 \\2"
# Write the raw and C identifiers.
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Fake it for dumpbin and say T for any non-static function,
# D for any global variable and I for any imported variable.
# Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
" {if(hide[section]) next};"\
" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
# Check to see that the pipe works correctly.
pipe_works=no
rm -f conftest*
cat > conftest.$ac_ext <<_LT_EOF
#ifdef __cplusplus
extern "C" {
#endif
char nm_test_var;
void nm_test_func(void);
void nm_test_func(void){}
#ifdef __cplusplus
}
#endif
int main(){nm_test_var='a';nm_test_func();return(0);}
_LT_EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
else
rm -f "$nlist"T
fi
# Make sure that we snagged all the symbols we need.
if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
/* DATA imports from DLLs on WIN32 can't be const, because runtime
relocations are performed -- see ld's documentation on pseudo-relocs. */
# define LT@&t@_DLSYM_CONST
#elif defined __osf__
/* This system does not cope well with relocations in const data. */
# define LT@&t@_DLSYM_CONST
#else
# define LT@&t@_DLSYM_CONST const
#endif
#ifdef __cplusplus
extern "C" {
#endif
_LT_EOF
# Now generate the symbol file.
eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
cat <<_LT_EOF >> conftest.$ac_ext
/* The mapping between symbol names and symbols. */
LT@&t@_DLSYM_CONST struct {
const char *name;
void *address;
}
lt__PROGRAM__LTX_preloaded_symbols[[]] =
{
{ "@PROGRAM@", (void *) 0 },
_LT_EOF
$SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
cat <<\_LT_EOF >> conftest.$ac_ext
{0, (void *) 0}
};
/* This works around a problem in FreeBSD linker */
#ifdef FREEBSD_WORKAROUND
static const void *lt_preloaded_setup() {
return lt__PROGRAM__LTX_preloaded_symbols;
}
#endif
#ifdef __cplusplus
}
#endif
_LT_EOF
# Now try linking the two files.
mv conftest.$ac_objext conftstm.$ac_objext
lt_globsym_save_LIBS=$LIBS
lt_globsym_save_CFLAGS=$CFLAGS
LIBS=conftstm.$ac_objext
CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
pipe_works=yes
fi
LIBS=$lt_globsym_save_LIBS
CFLAGS=$lt_globsym_save_CFLAGS
else
echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
fi
else
echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
fi
else
echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
fi
else
echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
cat conftest.$ac_ext >&5
fi
rm -rf conftest* conftst*
# Do not use the global_symbol_pipe unless it works.
if test yes = "$pipe_works"; then
break
else
lt_cv_sys_global_symbol_pipe=
fi
done
])
if test -z "$lt_cv_sys_global_symbol_pipe"; then
lt_cv_sys_global_symbol_to_cdecl=
fi
if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
AC_MSG_RESULT(failed)
else
AC_MSG_RESULT(ok)
fi
# Response file support.
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
nm_file_list_spec='@'
elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
nm_file_list_spec='@'
fi
_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
[Take the output of nm and produce a listing of raw symbols and C names])
_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
[Transform the output of nm in a proper C declaration])
_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
[Transform the output of nm into a list of symbols to manually relocate])
_LT_DECL([global_symbol_to_c_name_address],
[lt_cv_sys_global_symbol_to_c_name_address], [1],
[Transform the output of nm in a C name address pair])
_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
[lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
[Transform the output of nm in a C name address pair when lib prefix is needed])
_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
[The name lister interface])
_LT_DECL([], [nm_file_list_spec], [1],
[Specify filename containing input files for $NM])
]) # _LT_CMD_GLOBAL_SYMBOLS
# _LT_COMPILER_PIC([TAGNAME])
# ---------------------------
m4_defun([_LT_COMPILER_PIC],
[m4_require([_LT_TAG_COMPILER])dnl
_LT_TAGVAR(lt_prog_compiler_wl, $1)=
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_static, $1)=
m4_if([$1], [CXX], [
# C++ specific cases for pic, static, wl, etc.
if test yes = "$GXX"; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
# adding the '-m68020' flag to GCC prevents building anything better,
# like '-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
;;
beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
mingw* | cygwin* | os2* | pw32* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
case $host_os in
os2*)
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
;;
esac
;;
darwin* | rhapsody*)
# PIC is the default on this platform
# Common symbols not allowed in MH_DYLIB files
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
;;
*djgpp*)
# DJGPP does not support shared libraries at all
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
;;
haiku*)
# PIC is the default for Haiku.
# The "-static" flag exists, but is broken.
_LT_TAGVAR(lt_prog_compiler_static, $1)=
;;
interix[[3-9]]*)
# Interix 3.x gcc -fpic/-fPIC options generate broken code.
# Instead, we relocate shared libraries at runtime.
;;
sysv4*MP*)
if test -d /usr/nec; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
fi
;;
hpux*)
# PIC is the default for 64-bit PA HP-UX, but not for 32-bit
# PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
# sets the default TLS model and affects inlining.
case $host_cpu in
hppa*64*)
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
esac
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
esac
else
case $host_os in
aix[[4-9]]*)
# All AIX code is PIC.
if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
fi
;;
chorus*)
case $cc_basename in
cxch68*)
# Green Hills C++ Compiler
# _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
;;
esac
;;
mingw* | cygwin* | os2* | pw32* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
;;
dgux*)
case $cc_basename in
ec++*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
;;
ghcx*)
# Green Hills C++ Compiler
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
*)
;;
esac
;;
freebsd* | dragonfly*)
# FreeBSD uses GNU C++
;;
hpux9* | hpux10* | hpux11*)
case $cc_basename in
CC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
if test ia64 != "$host_cpu"; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
fi
;;
aCC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
;;
esac
;;
*)
;;
esac
;;
interix*)
# This is c89, which is MS Visual C++ (no shared libs)
# Anyone wants to do a port?
;;
irix5* | irix6* | nonstopux*)
case $cc_basename in
CC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
# CC pic flag -KPIC is the default.
;;
*)
;;
esac
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
ecpc* )
# old Intel C++ for x86_64, which still supported -KPIC.
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
icpc* )
# Intel C++, used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
cxx*)
# Compaq C++
# Make sure the PIC flag is empty. It appears that all Alpha
# Linux and Compaq Tru64 Unix objects are PIC.
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
# IBM XL 8.0, 9.0 on PPC and BlueGene
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
esac
;;
esac
;;
lynxos*)
;;
m88k*)
;;
mvs*)
case $cc_basename in
cxx*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
;;
*)
;;
esac
;;
netbsd*)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
;;
osf3* | osf4* | osf5*)
case $cc_basename in
KCC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
;;
RCC*)
# Rational C++ 2.4.1
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
cxx*)
# Digital/Compaq C++
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# Make sure the PIC flag is empty. It appears that all Alpha
# Linux and Compaq Tru64 Unix objects are PIC.
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
*)
;;
esac
;;
psos*)
;;
solaris*)
case $cc_basename in
CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
gcx*)
# Green Hills C++ Compiler
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
;;
*)
;;
esac
;;
sunos4*)
case $cc_basename in
CC*)
# Sun C++ 4.x
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
lcc*)
# Lucid
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
*)
;;
esac
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
case $cc_basename in
CC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
esac
;;
tandem*)
case $cc_basename in
NCC*)
# NonStop-UX NCC 3.20
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
;;
*)
;;
esac
;;
vxworks*)
;;
*)
_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
;;
esac
fi
],
[
if test yes = "$GCC"; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
# adding the '-m68020' flag to GCC prevents building anything better,
# like '-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
;;
beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
# Although the cygwin gcc ignores -fPIC, still need this for old-style
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
case $host_os in
os2*)
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
;;
esac
;;
darwin* | rhapsody*)
# PIC is the default on this platform
# Common symbols not allowed in MH_DYLIB files
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
;;
haiku*)
# PIC is the default for Haiku.
# The "-static" flag exists, but is broken.
_LT_TAGVAR(lt_prog_compiler_static, $1)=
;;
hpux*)
# PIC is the default for 64-bit PA HP-UX, but not for 32-bit
# PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
# sets the default TLS model and affects inlining.
case $host_cpu in
hppa*64*)
# +Z the default
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
esac
;;
interix[[3-9]]*)
# Interix 3.x gcc -fpic/-fPIC options generate broken code.
# Instead, we relocate shared libraries at runtime.
;;
msdosdjgpp*)
# Just because we use GCC doesn't mean we suddenly get shared libraries
# on systems that don't support them.
_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
enable_shared=no
;;
*nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
;;
sysv4*MP*)
if test -d /usr/nec; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
fi
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
esac
case $cc_basename in
nvcc*) # Cuda Compiler Driver 2.2
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
fi
;;
esac
else
# PORTME Check for flag to pass linker flags through the system compiler.
case $host_os in
aix*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
fi
;;
darwin* | rhapsody*)
# PIC is the default on this platform
# Common symbols not allowed in MH_DYLIB files
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
case $cc_basename in
nagfor*)
# NAG Fortran compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
esac
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
case $host_os in
os2*)
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
;;
esac
;;
hpux9* | hpux10* | hpux11*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
;;
esac
# Is there a better lt_prog_compiler_static that works with the bundled CC?
_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
;;
irix5* | irix6* | nonstopux*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# PIC (with -KPIC) is the default.
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
# old Intel for x86_64, which still supported -KPIC.
ecc*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# Lahey Fortran 8.1.
lf95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
;;
nagfor*)
# NAG Fortran compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
tcc*)
# Fabrice Bellard et al's Tiny C Compiler
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
ccc*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# All Alpha code is PIC.
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
xl* | bgxl* | bgf* | mpixl*)
# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
# Sun Fortran 8.3 passes all unrecognized flags to the linker
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)=''
;;
*Sun\ F* | *Sun*Fortran*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
*Sun\ C*)
# Sun C 5.9
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
;;
*Intel*\ [[CF]]*Compiler*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
*Portland\ Group*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
esac
;;
esac
;;
newsos6)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
*nto* | *qnx*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
# it will coredump.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
;;
osf3* | osf4* | osf5*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# All OSF/1 code is PIC.
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
rdos*)
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
solaris*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
case $cc_basename in
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
esac
;;
sunos4*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
sysv4*MP*)
if test -d /usr/nec; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
unicos*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
;;
uts4*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
*)
_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
;;
esac
fi
])
case $host_os in
# For platforms that do not support PIC, -DPIC is meaningless:
*djgpp*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
;;
*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
;;
esac
AC_CACHE_CHECK([for $compiler option to produce PIC],
[_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
[_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
#
# Check to make sure the PIC flag actually works.
#
if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
_LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
[_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
[$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
[case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
"" | " "*) ;;
*) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
esac],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
fi
_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
[Additional compiler flags for building library objects])
_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
[How to pass a linker flag through the compiler])
#
# Check to make sure the static flag actually works.
#
wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
_LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
$lt_tmp_static_flag,
[],
[_LT_TAGVAR(lt_prog_compiler_static, $1)=])
_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
[Compiler flag to prevent dynamic linking])
])# _LT_COMPILER_PIC
# _LT_LINKER_SHLIBS([TAGNAME])
# ----------------------------
# See if the linker supports building shared libraries.
m4_defun([_LT_LINKER_SHLIBS],
[AC_REQUIRE([LT_PATH_LD])dnl
AC_REQUIRE([LT_PATH_NM])dnl
m4_require([_LT_PATH_MANIFEST_TOOL])dnl
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
m4_require([_LT_TAG_COMPILER])dnl
AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
m4_if([$1], [CXX], [
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
case $host_os in
aix[[4-9]]*)
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to GNU nm, but means don't demangle to AIX nm.
# Without the "-l" option, or with the "-B" option, AIX nm treats
# weak defined symbols like other global defined symbols, whereas
# GNU nm marks them as "W".
# While the 'weak' keyword is ignored in the Export File, we need
# it in the Import File for the 'aix-soname' feature, so we have
# to replace the "-B" option with "-P" for AIX nm.
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
_LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
cl*)
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
_LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
;;
esac
;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
esac
], [
runpath_var=
_LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(archive_cmds, $1)=
_LT_TAGVAR(archive_expsym_cmds, $1)=
_LT_TAGVAR(compiler_needs_object, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
_LT_TAGVAR(hardcode_automatic, $1)=no
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
_LT_TAGVAR(inherit_rpath, $1)=no
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(old_archive_from_new_cmds, $1)=
_LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
_LT_TAGVAR(thread_safe_flag_spec, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
# include_expsyms should be a list of space-separated symbols to be *always*
# included in the symbol list
_LT_TAGVAR(include_expsyms, $1)=
# exclude_expsyms can be an extended regexp of symbols to exclude
# it will be wrapped by ' (' and ')$', so one must not match beginning or
# end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
# as well as any symbol that contains 'd'.
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
# platforms (ab)use it in PIC code, but their linkers get confused if
# the symbol is explicitly referenced. Since portable code cannot
# rely on this symbol name, it's probably fine to never include it in
# preloaded symbol tables.
# Exclude shared library initialization/finalization symbols.
dnl Note also adjust exclude_expsyms for C++ above.
extract_expsyms_cmds=
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd* | bitrig*)
with_gnu_ld=no
;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
# On some targets, GNU ld is compatible enough with the native linker
# that we're better off using the native interface for both.
lt_use_gnu_ld_interface=no
if test yes = "$with_gnu_ld"; then
case $host_os in
aix*)
# The AIX port of GNU ld has always aspired to compatibility
# with the native linker. However, as the warning in the GNU ld
# block says, versions before 2.19.5* couldn't really create working
# shared libraries, regardless of the interface used.
case `$LD -v 2>&1` in
*\ \(GNU\ Binutils\)\ 2.19.5*) ;;
*\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
*\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
*)
lt_use_gnu_ld_interface=yes
;;
esac
;;
*)
lt_use_gnu_ld_interface=yes
;;
esac
fi
if test yes = "$lt_use_gnu_ld_interface"; then
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='$wl'
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
runpath_var=LD_RUN_PATH
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
_LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
supports_anon_versioning=no
case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
*\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
*\ 2.11.*) ;; # other 2.11 versions
*) supports_anon_versioning=yes ;;
esac
# See if GNU ld supports shared libraries.
case $host_os in
aix[[3-9]]*)
# On AIX/PPC, the GNU linker is very broken
if test ia64 != "$host_cpu"; then
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
*** Warning: the GNU linker, at least up to release 2.19, is reported
*** to be unable to reliably create shared libraries on AIX.
*** Therefore, libtool is disabling shared libraries support. If you
*** really care for shared libraries, you may want to install binutils
*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
*** You will then need to restart the configuration process.
_LT_EOF
fi
;;
amigaos*)
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
;;
esac
;;
beos*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
_LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file, use it as
# is; otherwise, prepend EXPORTS...
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp $export_symbols $output_objdir/$soname.def;
else
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
haiku*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
os2*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
shrext_cmds=.dll
_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
prefix_cmds="$SED"~
if test EXPORTS = "`$SED 1q $export_symbols`"; then
prefix_cmds="$prefix_cmds -e 1d";
fi~
prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
if test linux-dietlibc = "$host_os"; then
case $cc_basename in
diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
esac
fi
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
&& test no = "$tmp_diet"
then
tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group f77 and f90 compilers
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
tmp_addflag=' -i_dynamic -nofor_main' ;;
ifc* | ifort*) # Intel Fortran compiler
tmp_addflag=' -nofor_main' ;;
lf95*) # Lahey Fortran 8.1
_LT_TAGVAR(whole_archive_flag_spec, $1)=
tmp_sharedflag='--shared' ;;
nagfor*) # NAGFOR 5.3
tmp_sharedflag='-Wl,-shared' ;;
xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
nvcc*) # Cuda Compiler Driver 2.2
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
tmp_sharedflag='-G' ;;
esac
_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
tcc*)
_LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
;;
xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
_LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
solaris*)
if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
*** Warning: The releases 2.8.* of the GNU linker cannot reliably
*** create shared libraries on Solaris systems. Therefore, libtool
*** is disabling shared libraries support. We urge you to upgrade GNU
*** binutils to release 2.9.1 or newer. Another option is to modify
*** your PATH or compiler configuration so that the native linker is
*** used, and then restart.
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
*** reliably create shared libraries on SCO systems. Therefore, libtool
*** is disabling shared libraries support. We urge you to upgrade GNU
*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
*** your PATH or compiler configuration so that the native linker is
*** used, and then restart.
_LT_EOF
;;
*)
# For security reasons, it is highly recommended that you always
# use absolute paths for naming shared libraries, and exclude the
# DT_RUNPATH tag from executables and libraries. But doing so
# requires that you compile everything twice, which is a pain.
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
;;
sunos4*)
_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
wlarc=
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
runpath_var=
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
else
# PORTME fill in a description of your system's linker (not GNU ld)
case $host_os in
aix3*)
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
_LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
_LT_TAGVAR(hardcode_direct, $1)=unsupported
fi
;;
aix[[4-9]]*)
if test ia64 = "$host_cpu"; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
no_entry_flag=
else
# If we're using GNU nm, then we don't want the "-C" option.
# -C means demangle to GNU nm, but means don't demangle to AIX nm.
# Without the "-l" option, or with the "-B" option, AIX nm treats
# weak defined symbols like other global defined symbols, whereas
# GNU nm marks them as "W".
# While the 'weak' keyword is ignored in the Export File, we need
# it in the Import File for the 'aix-soname' feature, so we have
# to replace the "-B" option with "-P" for AIX nm.
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# have runtime linking enabled, and use it for executables.
# For shared libraries, we enable/disable runtime linking
# depending on the kind of the shared library created -
# when "with_aix_soname,aix_use_runtimelinking" is:
# "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
# "aix,yes" lib.so shared, rtl:yes, for executables
# lib.a static archive
# "both,no" lib.so.V(shr.o) shared, rtl:yes
# lib.a(lib.so.V) shared, rtl:no, for executables
# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
# lib.a(lib.so.V) shared, rtl:no
# "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
# lib.a static archive
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
aix_use_runtimelinking=yes
break
fi
done
if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
# With aix-soname=svr4, we create the lib.so.V shared archives only,
# so we don't have lib.a shared libs to link our executables.
# We have to force runtime linking in this case.
aix_use_runtimelinking=yes
LDFLAGS="$LDFLAGS -Wl,-brtl"
fi
;;
esac
exp_sym_flag='-bexport'
no_entry_flag='-bnoentry'
fi
# When large executables or shared objects are built, AIX ld can
# have problems creating the table of contents. If linking a library
# or program results in "error TOC overflow" add -mminimal-toc to
# CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
# enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
_LT_TAGVAR(archive_cmds, $1)=''
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='$wl-f,'
case $with_aix_soname,$aix_use_runtimelinking in
aix,*) ;; # traditional, no import file
svr4,* | *,yes) # use import file
# The Import File defines what to hardcode.
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
;;
esac
if test yes = "$GCC"; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`$CC -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
_LT_TAGVAR(hardcode_direct, $1)=unsupported
# It fails to find uninstalled libraries when the uninstalled
# path is not listed in the libpath. Setting hardcode_minus_L
# to unsupported forces relinking
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=
fi
;;
esac
shared_flag='-shared'
if test yes = "$aix_use_runtimelinking"; then
shared_flag="$shared_flag "'$wl-G'
fi
# Need to ensure runtime linking is disabled for the traditional
# shared library, or the linker may eventually find shared libraries
# /with/ Import File - we do not want to mix them.
shared_flag_aix='-shared'
shared_flag_svr4='-shared $wl-G'
else
# not using gcc
if test ia64 = "$host_cpu"; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
if test yes = "$aix_use_runtimelinking"; then
shared_flag='$wl-G'
else
shared_flag='$wl-bM:SRE'
fi
shared_flag_aix='$wl-bM:SRE'
shared_flag_svr4='$wl-G'
fi
fi
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
_LT_TAGVAR(always_export_symbols, $1)=yes
if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
else
if test ia64 = "$host_cpu"; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
_LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
if test yes = "$with_gnu_ld"; then
# We only use this code for GNU lds that support --whole-archive.
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
_LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
# -brtl affects multiple linker settings, -berok does not and is overridden later
compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
if test svr4 != "$with_aix_soname"; then
# This is similar to how AIX traditionally builds its shared libraries.
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
fi
if test aix != "$with_aix_soname"; then
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
else
# used by -dlpreopen to get the symbols
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
fi
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
fi
fi
;;
amigaos*)
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
;;
esac
;;
bsdi[[45]]*)
_LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
case $cc_basename in
cl*)
# Native MSVC
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp "$export_symbols" "$output_objdir/$soname.def";
echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
else
$SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
fi~
$CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
lt_tool_outputfile="@TOOL_OUTPUT@"~
case $lt_outputfile in
*.exe|*.EXE) ;;
*)
lt_outputfile=$lt_outputfile.exe
lt_tool_outputfile=$lt_tool_outputfile.exe
;;
esac~
if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
$MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
$RM "$lt_outputfile.manifest";
fi'
;;
*)
# Assume MSVC wrapper
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
# FIXME: Should let the user specify the lib program.
_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
esac
;;
darwin* | rhapsody*)
_LT_DARWIN_LINKER_FEATURES($1)
;;
dgux*)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
# FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
# support. Future versions do this automatically, but an explicit c++rt0.o
# does not break anything, and helps significantly (at the cost of a little
# extra space).
freebsd2.2*)
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
# Unfortunately, older versions of FreeBSD 2 do not have this feature.
freebsd2.*)
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
freebsd* | dragonfly*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
hpux9*)
if test yes = "$GCC"; then
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
else
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
;;
hpux10*)
if test yes,no = "$GCC,$with_gnu_ld"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
if test no = "$with_gnu_ld"; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
fi
;;
hpux11*)
if test yes,no = "$GCC,$with_gnu_ld"; then
case $host_cpu in
hppa*64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
case $host_cpu in
hppa*64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
m4_if($1, [], [
# Older versions of the 11.00 compiler do not understand -b yet
# (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
_LT_LINKER_OPTION([if $CC understands -b],
_LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
[_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
[_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
[_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
;;
esac
fi
if test no = "$with_gnu_ld"; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
hppa*64*|ia64*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*)
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
if test yes = "$GCC"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
# This should be the same for all languages, so no per-tag cache variable.
AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
[lt_cv_irix_exported_symbol],
[save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
AC_LINK_IFELSE(
[AC_LANG_SOURCE(
[AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
[C++], [[int foo (void) { return 0; }]],
[Fortran 77], [[
subroutine foo
end]],
[Fortran], [[
subroutine foo
end]])])],
[lt_cv_irix_exported_symbol=yes],
[lt_cv_irix_exported_symbol=no])
LDFLAGS=$save_LDFLAGS])
if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
linux*)
case $cc_basename in
tcc*)
# Fabrice Bellard et al's Tiny C Compiler
_LT_TAGVAR(ld_shlibs, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
newsos6)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*nto* | *qnx*)
;;
openbsd* | bitrig*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
fi
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
os2*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
shrext_cmds=.dll
_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
prefix_cmds="$SED"~
if test EXPORTS = "`$SED 1q $export_symbols`"; then
prefix_cmds="$prefix_cmds -e 1d";
fi~
prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
osf3*)
if test yes = "$GCC"; then
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
;;
osf4* | osf5*) # as osf3* with the addition of -msym flag
if test yes = "$GCC"; then
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
$CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
;;
solaris*)
_LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
if test yes = "$GCC"; then
wlarc='$wl'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
wlarc=''
_LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
;;
*)
wlarc='$wl'
_LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
;;
esac
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
# but understands '-z linker_flag'. GCC discards it without '$wl',
# but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?)
if test yes = "$GCC"; then
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
fi
;;
esac
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
sunos4*)
if test sequent = "$host_vendor"; then
# Use $CC to link under sequent, because it throws in some extra .o
# files that make .init and .fini sections work.
_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
sysv4)
case $host_vendor in
sni)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
;;
siemens)
## LD is ld it makes a PLAMLIB
## CC just makes a GrossModule.
_LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
_LT_TAGVAR(hardcode_direct, $1)=no
;;
motorola)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
;;
esac
runpath_var='LD_RUN_PATH'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
sysv4.3*)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
;;
sysv4*MP*)
if test -d /usr/nec; then
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var=LD_RUN_PATH
hardcode_runpath_var=yes
_LT_TAGVAR(ld_shlibs, $1)=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
if test yes = "$GCC"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
sysv5* | sco3.2v5* | sco5v6*)
# Note: We CANNOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
runpath_var='LD_RUN_PATH'
if test yes = "$GCC"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
uts4*)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*)
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
if test sni = "$host_vendor"; then
case $host in
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
;;
esac
fi
fi
])
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
_LT_DECL([], [extract_expsyms_cmds], [2],
[The commands to extract the exported symbol list from a shared archive])
#
# Do we need to explicitly link libc?
#
case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
x|xyes)
# Assume -lc should be added
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
if test yes,yes = "$GCC,$enable_shared"; then
case $_LT_TAGVAR(archive_cmds, $1) in
*'~'*)
# FIXME: we may have to deal with multi-command sequences.
;;
'$CC '*)
# Test whether the compiler implicitly links with -lc since on some
# systems, -lgcc has to come before -lc. If gcc already passes -lc
# to ld, don't add -lc before -lgcc.
AC_CACHE_CHECK([whether -lc should be explicitly linked in],
[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
[$RM conftest*
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
soname=conftest
lib=conftest
libobjs=conftest.$ac_objext
deplibs=
wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
compiler_flags=-v
linker_flags=-v
verstring=
output_objdir=.
libname=conftest
lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
_LT_TAGVAR(allow_undefined_flag, $1)=
if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
then
lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
else
lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
fi
_LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
else
cat conftest.err 1>&5
fi
$RM conftest*
])
_LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
;;
esac
fi
;;
esac
_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
[Whether or not to add -lc for building shared libraries])
_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
[enable_shared_with_static_runtimes], [0],
[Whether or not to disallow shared libs when runtime libs are static])
_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
[Compiler flag to allow reflexive dlopens])
_LT_TAGDECL([], [whole_archive_flag_spec], [1],
[Compiler flag to generate shared objects directly from archives])
_LT_TAGDECL([], [compiler_needs_object], [1],
[Whether the compiler copes with passing no objects directly])
_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
[Create an old-style archive from a shared archive])
_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
[Create a temporary old-style archive to link instead of a shared archive])
_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
_LT_TAGDECL([], [archive_expsym_cmds], [2])
_LT_TAGDECL([], [module_cmds], [2],
[Commands used to build a loadable module if different from building
a shared archive.])
_LT_TAGDECL([], [module_expsym_cmds], [2])
_LT_TAGDECL([], [with_gnu_ld], [1],
[Whether we are building with GNU ld or not])
_LT_TAGDECL([], [allow_undefined_flag], [1],
[Flag that allows shared libraries with undefined symbols to be built])
_LT_TAGDECL([], [no_undefined_flag], [1],
[Flag that enforces no undefined symbols])
_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
[Flag to hardcode $libdir into a binary during linking.
This must work even if $libdir does not exist])
_LT_TAGDECL([], [hardcode_libdir_separator], [1],
[Whether we need a single "-rpath" flag with a separated argument])
_LT_TAGDECL([], [hardcode_direct], [0],
[Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
DIR into the resulting binary])
_LT_TAGDECL([], [hardcode_direct_absolute], [0],
[Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
DIR into the resulting binary and the resulting library dependency is
"absolute", i.e impossible to change by setting $shlibpath_var if the
library is relocated])
_LT_TAGDECL([], [hardcode_minus_L], [0],
[Set to "yes" if using the -LDIR flag during linking hardcodes DIR
into the resulting binary])
_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
[Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
into the resulting binary])
_LT_TAGDECL([], [hardcode_automatic], [0],
[Set to "yes" if building a shared library automatically hardcodes DIR
into the library and all subsequent libraries and executables linked
against it])
_LT_TAGDECL([], [inherit_rpath], [0],
[Set to yes if linker adds runtime paths of dependent libraries
to runtime path list])
_LT_TAGDECL([], [link_all_deplibs], [0],
[Whether libtool must link a program against all its dependency libraries])
_LT_TAGDECL([], [always_export_symbols], [0],
[Set to "yes" if exported symbols are required])
_LT_TAGDECL([], [export_symbols_cmds], [2],
[The commands to list exported symbols])
_LT_TAGDECL([], [exclude_expsyms], [1],
[Symbols that should not be listed in the preloaded symbols])
_LT_TAGDECL([], [include_expsyms], [1],
[Symbols that must always be exported])
_LT_TAGDECL([], [prelink_cmds], [2],
[Commands necessary for linking programs (against libraries) with templates])
_LT_TAGDECL([], [postlink_cmds], [2],
[Commands necessary for finishing linking programs])
_LT_TAGDECL([], [file_list_spec], [1],
[Specify filename containing input files])
dnl FIXME: Not yet implemented
dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
dnl [Compiler flag to generate thread safe objects])
])# _LT_LINKER_SHLIBS
# _LT_LANG_C_CONFIG([TAG])
# ------------------------
# Ensure that the configuration variables for a C compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
# the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_C_CONFIG],
[m4_require([_LT_DECL_EGREP])dnl
lt_save_CC=$CC
AC_LANG_PUSH(C)
# Source file extension for C test sources.
ac_ext=c
# Object file extension for compiled C test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# Code to be used in simple compile tests
lt_simple_compile_test_code="int some_variable = 0;"
# Code to be used in simple link tests
lt_simple_link_test_code='int main(){return(0);}'
_LT_TAG_COMPILER
# Save the default compiler, since it gets overwritten when the other
# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
compiler_DEFAULT=$CC
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
if test -n "$compiler"; then
_LT_COMPILER_NO_RTTI($1)
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_SYS_DYNAMIC_LINKER($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
LT_SYS_DLOPEN_SELF
_LT_CMD_STRIPLIB
# Report what library types will actually be built
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
if test ia64 != "$host_cpu"; then
case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
yes,aix,yes) ;; # shared object as lib.so file only
yes,svr4,*) ;; # shared object as lib.so archive member only
yes,*) enable_static=no ;; # shared object in lib.a archive as well
esac
fi
;;
esac
AC_MSG_RESULT([$enable_shared])
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
_LT_CONFIG($1)
fi
AC_LANG_POP
CC=$lt_save_CC
])# _LT_LANG_C_CONFIG
# _LT_LANG_CXX_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for a C++ compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
# the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_CXX_CONFIG],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_PATH_MANIFEST_TOOL])dnl
if test -n "$CXX" && ( test no != "$CXX" &&
( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
(test g++ != "$CXX"))); then
AC_PROG_CXXCPP
else
_lt_caught_CXX_error=yes
fi
AC_LANG_PUSH(C++)
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(archive_expsym_cmds, $1)=
_LT_TAGVAR(compiler_needs_object, $1)=no
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
_LT_TAGVAR(hardcode_automatic, $1)=no
_LT_TAGVAR(inherit_rpath, $1)=no
_LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
_LT_TAGVAR(reload_flag, $1)=$reload_flag
_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
# Source file extension for C++ test sources.
ac_ext=cpp
# Object file extension for compiled C++ test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# No sense in running all these tests if we already determined that
# the CXX compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
if test yes != "$_lt_caught_CXX_error"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="int some_variable = 0;"
# Code to be used in simple link tests
lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_CFLAGS=$CFLAGS
lt_save_LD=$LD
lt_save_GCC=$GCC
GCC=$GXX
lt_save_with_gnu_ld=$with_gnu_ld
lt_save_path_LD=$lt_cv_path_LD
if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
else
$as_unset lt_cv_prog_gnu_ld
fi
if test -n "${lt_cv_path_LDCXX+set}"; then
lt_cv_path_LD=$lt_cv_path_LDCXX
else
$as_unset lt_cv_path_LD
fi
test -z "${LDCXX+set}" || LD=$LDCXX
CC=${CXX-"c++"}
CFLAGS=$CXXFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
if test -n "$compiler"; then
# We don't want -fno-exception when compiling C++ code, so set the
# no_builtin_flag separately
if test yes = "$GXX"; then
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
else
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
fi
if test yes = "$GXX"; then
# Set up default GNU C++ configuration
LT_PATH_LD
# Check if GNU C++ uses GNU ld as the underlying linker, since the
# archiving commands below assume that GNU ld is being used.
if test yes = "$with_gnu_ld"; then
_LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# If archive_cmds runs LD, not CC, wlarc should be empty
# XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
# investigate it a little bit more. (MM)
wlarc='$wl'
# ancient GNU ld didn't support --whole-archive et. al.
if eval "`$CC -print-prog-name=ld` --help 2>&1" |
$GREP 'no-whole-archive' > /dev/null; then
_LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
else
with_gnu_ld=no
wlarc=
# A generic and very simple default shared library creation
# command for GNU C++ for the case where it uses the native
# linker, instead of GNU ld. If possible, this setting should
# overridden to take advantage of the native linker features on
# the platform it is being used on.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
GXX=no
with_gnu_ld=no
wlarc=
fi
# PORTME: fill in a description of your system's C++ link characteristics
AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
_LT_TAGVAR(ld_shlibs, $1)=yes
case $host_os in
aix3*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aix[[4-9]]*)
if test ia64 = "$host_cpu"; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
no_entry_flag=
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# have runtime linking enabled, and use it for executables.
# For shared libraries, we enable/disable runtime linking
# depending on the kind of the shared library created -
# when "with_aix_soname,aix_use_runtimelinking" is:
# "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
# "aix,yes" lib.so shared, rtl:yes, for executables
# lib.a static archive
# "both,no" lib.so.V(shr.o) shared, rtl:yes
# lib.a(lib.so.V) shared, rtl:no, for executables
# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
# lib.a(lib.so.V) shared, rtl:no
# "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
# lib.a static archive
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
case $ld_flag in
*-brtl*)
aix_use_runtimelinking=yes
break
;;
esac
done
if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
# With aix-soname=svr4, we create the lib.so.V shared archives only,
# so we don't have lib.a shared libs to link our executables.
# We have to force runtime linking in this case.
aix_use_runtimelinking=yes
LDFLAGS="$LDFLAGS -Wl,-brtl"
fi
;;
esac
exp_sym_flag='-bexport'
no_entry_flag='-bnoentry'
fi
# When large executables or shared objects are built, AIX ld can
# have problems creating the table of contents. If linking a library
# or program results in "error TOC overflow" add -mminimal-toc to
# CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
# enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
_LT_TAGVAR(archive_cmds, $1)=''
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='$wl-f,'
case $with_aix_soname,$aix_use_runtimelinking in
aix,*) ;; # no import file
svr4,* | *,yes) # use import file
# The Import File defines what to hardcode.
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
;;
esac
if test yes = "$GXX"; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`$CC -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
_LT_TAGVAR(hardcode_direct, $1)=unsupported
# It fails to find uninstalled libraries when the uninstalled
# path is not listed in the libpath. Setting hardcode_minus_L
# to unsupported forces relinking
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=
fi
esac
shared_flag='-shared'
if test yes = "$aix_use_runtimelinking"; then
shared_flag=$shared_flag' $wl-G'
fi
# Need to ensure runtime linking is disabled for the traditional
# shared library, or the linker may eventually find shared libraries
# /with/ Import File - we do not want to mix them.
shared_flag_aix='-shared'
shared_flag_svr4='-shared $wl-G'
else
# not using gcc
if test ia64 = "$host_cpu"; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
if test yes = "$aix_use_runtimelinking"; then
shared_flag='$wl-G'
else
shared_flag='$wl-bM:SRE'
fi
shared_flag_aix='$wl-bM:SRE'
shared_flag_svr4='$wl-G'
fi
fi
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to
# export.
_LT_TAGVAR(always_export_symbols, $1)=yes
if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
# The "-G" linker flag allows undefined symbols.
_LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
# Determine the default libpath from the value encoded in an empty
# executable.
_LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
else
if test ia64 = "$host_cpu"; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
_LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
if test yes = "$with_gnu_ld"; then
# We only use this code for GNU lds that support --whole-archive.
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
_LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
# -brtl affects multiple linker settings, -berok does not and is overridden later
compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
if test svr4 != "$with_aix_soname"; then
# This is similar to how AIX traditionally builds its shared
# libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
fi
if test aix != "$with_aix_soname"; then
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
else
# used by -dlpreopen to get the symbols
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
fi
_LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
fi
fi
;;
beos*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
chorus*)
case $cc_basename in
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
;;
cygwin* | mingw* | pw32* | cegcc*)
case $GXX,$cc_basename in
,cl* | no,cl*)
# Native MSVC
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp "$export_symbols" "$output_objdir/$soname.def";
echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
else
$SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
fi~
$CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
lt_tool_outputfile="@TOOL_OUTPUT@"~
case $lt_outputfile in
*.exe|*.EXE) ;;
*)
lt_outputfile=$lt_outputfile.exe
lt_tool_outputfile=$lt_tool_outputfile.exe
;;
esac~
func_to_tool_file "$lt_outputfile"~
if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
$MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
$RM "$lt_outputfile.manifest";
fi'
;;
*)
# g++
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file, use it as
# is; otherwise, prepend EXPORTS...
_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
cp $export_symbols $output_objdir/$soname.def;
else
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
$CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
;;
darwin* | rhapsody*)
_LT_DARWIN_LINKER_FEATURES($1)
;;
os2*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
shrext_cmds=.dll
_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
$ECHO EXPORTS >> $output_objdir/$libname.def~
prefix_cmds="$SED"~
if test EXPORTS = "`$SED 1q $export_symbols`"; then
prefix_cmds="$prefix_cmds -e 1d";
fi~
prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
dgux*)
case $cc_basename in
ec++*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
ghcx*)
# Green Hills C++ Compiler
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
;;
freebsd2.*)
# C++ shared libraries reported to be fairly broken before
# switch to ELF
_LT_TAGVAR(ld_shlibs, $1)=no
;;
freebsd-elf*)
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
;;
freebsd* | dragonfly*)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
haiku*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
hpux9*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
# but as the default
# location of the library.
case $cc_basename in
CC*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aCC*)
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
#
# There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
;;
hpux10*|hpux11*)
if test no = "$with_gnu_ld"; then
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
hppa*64*|ia64*)
;;
*)
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
;;
esac
fi
case $host_cpu in
hppa*64*|ia64*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
*)
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
# but as the default
# location of the library.
;;
esac
case $cc_basename in
CC*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aCC*)
case $host_cpu in
hppa*64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
#
# There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
if test no = "$with_gnu_ld"; then
case $host_cpu in
hppa*64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
;;
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
irix5* | irix6*)
case $cc_basename in
CC*)
# SGI C++
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
# necessary to make sure instantiated templates are included
# in the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
;;
*)
if test yes = "$GXX"; then
if test no = "$with_gnu_ld"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
fi
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
esac
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
_LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
#
# There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# Archives containing C++ object files must be created using
# "CC -Bstatic", where "CC" is the KAI C++ compiler.
_LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
;;
icpc* | ecpc* )
# Intel C++
with_gnu_ld=yes
# version 8.0 and above of icpc choke on multiply defined symbols
# if we add $predep_objects and $postdep_objects, however 7.1 and
# earlier do not add the objects themselves.
case `$CC -V 2>&1` in
*"Version 7."*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
*) # Version 8.0 or newer
tmp_idyn=
case $host_cpu in
ia64*) tmp_idyn=' -i_dynamic';;
esac
_LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
esac
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
case `$CC -V` in
*pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
_LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
_LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
$RANLIB $oldlib'
_LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
rm -rf $tpldir~
$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
*) # Version 6 and above use weak symbols
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
esac
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
;;
cxx*)
# Compaq C++
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
runpath_var=LD_RUN_PATH
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
#
# There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
;;
xl* | mpixl* | bgxl*)
# IBM XL 8.0 on PPC, with GNU ld
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
_LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
_LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
# Not sure whether something based on
# $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
# would be better.
output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
# necessary to make sure instantiated templates are included
# in the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
;;
esac
;;
esac
;;
lynxos*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
m88k*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
mvs*)
case $cc_basename in
cxx*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
;;
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
wlarc=
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
fi
# Workaround some broken pre-1.5 toolchains
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
;;
*nto* | *qnx*)
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
openbsd* | bitrig*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
_LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
fi
output_verbose_link_cmd=func_echo_all
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
osf3* | osf4* | osf5*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
_LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Archives containing C++ object files must be created using
# the KAI C++ compiler.
case $host in
osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
esac
;;
RCC*)
# Rational C++ 2.4.1
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
cxx*)
case $host in
osf3*)
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
;;
*)
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
echo "-hidden">> $lib.exp~
$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
$RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
;;
esac
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
#
# There doesn't appear to be a way to prevent this compiler from
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes,no = "$GXX,$with_gnu_ld"; then
_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
case $host in
osf3*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
;;
esac
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
;;
psos*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
sunos4*)
case $cc_basename in
CC*)
# Sun C++ 4.x
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
lcc*)
# Lucid
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
;;
solaris*)
case $cc_basename in
CC* | sunCC*)
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
_LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
# but understands '-z linker_flag'.
# Supported since Solaris 2.6 (maybe 2.5.1?)
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
;;
esac
_LT_TAGVAR(link_all_deplibs, $1)=yes
output_verbose_link_cmd='func_echo_all'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
# necessary to make sure instantiated templates are included
# in the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
;;
gcx*)
# Green Hills C++ Compiler
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
# The C++ compiler must be used to create the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
;;
*)
# GNU C++ compiler with Solaris linker
if test yes,no = "$GXX,$with_gnu_ld"; then
_LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
if $CC --version | $GREP -v '^2\.7' > /dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
_LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
$CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
;;
esac
fi
;;
esac
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
sysv5* | sco3.2v5* | sco5v6*)
# Note: We CANNOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
'"$_LT_TAGVAR(old_archive_cmds, $1)"
_LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
'"$_LT_TAGVAR(reload_cmds, $1)"
;;
*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
tandem*)
case $cc_basename in
NCC*)
# NonStop-UX NCC 3.20
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
;;
vxworks*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
*)
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
;;
esac
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
_LT_TAGVAR(GCC, $1)=$GXX
_LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
_LT_SYS_HIDDEN_LIBDEPS($1)
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_SYS_DYNAMIC_LINKER($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
_LT_CONFIG($1)
fi # test -n "$compiler"
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
LDCXX=$LD
LD=$lt_save_LD
GCC=$lt_save_GCC
with_gnu_ld=$lt_save_with_gnu_ld
lt_cv_path_LDCXX=$lt_cv_path_LD
lt_cv_path_LD=$lt_save_path_LD
lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
fi # test yes != "$_lt_caught_CXX_error"
AC_LANG_POP
])# _LT_LANG_CXX_CONFIG
# _LT_FUNC_STRIPNAME_CNF
# ----------------------
# func_stripname_cnf prefix suffix name
# strip PREFIX and SUFFIX off of NAME.
# PREFIX and SUFFIX must not contain globbing or regex special
# characters, hashes, percent signs, but SUFFIX may contain a leading
# dot (in which case that matches only a dot).
#
# This function is identical to the (non-XSI) version of func_stripname,
# except this one can be used by m4 code that may be executed by configure,
# rather than the libtool script.
m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
AC_REQUIRE([_LT_DECL_SED])
AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
func_stripname_cnf ()
{
case @S|@2 in
.*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
esac
} # func_stripname_cnf
])# _LT_FUNC_STRIPNAME_CNF
# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
# ---------------------------------
# Figure out "hidden" library dependencies from verbose
# compiler output when linking a shared library.
# Parse the compiler output and extract the necessary
# objects, libraries and library flags.
m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
# Dependencies to place before and after the object being linked:
_LT_TAGVAR(predep_objects, $1)=
_LT_TAGVAR(postdep_objects, $1)=
_LT_TAGVAR(predeps, $1)=
_LT_TAGVAR(postdeps, $1)=
_LT_TAGVAR(compiler_lib_search_path, $1)=
dnl we can't use the lt_simple_compile_test_code here,
dnl because it contains code intended for an executable,
dnl not a library. It's possible we should let each
dnl tag define a new lt_????_link_test_code variable,
dnl but it's only used here...
m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
int a;
void foo (void) { a = 0; }
_LT_EOF
], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
class Foo
{
public:
Foo (void) { a = 0; }
private:
int a;
};
_LT_EOF
], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
subroutine foo
implicit none
integer*4 a
a=0
return
end
_LT_EOF
], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
subroutine foo
implicit none
integer a
a=0
return
end
_LT_EOF
], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
public class foo {
private int a;
public void bar (void) {
a = 0;
}
};
_LT_EOF
], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
package foo
func foo() {
}
_LT_EOF
])
_lt_libdeps_save_CFLAGS=$CFLAGS
case "$CC $CFLAGS " in #(
*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
esac
dnl Parse the compiler output and extract the necessary
dnl objects, libraries and library flags.
if AC_TRY_EVAL(ac_compile); then
# Parse the compiler output and extract the necessary
# objects, libraries and library flags.
# Sentinel used to keep track of whether or not we are before
# the conftest object file.
pre_test_object_deps_done=no
for p in `eval "$output_verbose_link_cmd"`; do
case $prev$p in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
# Remove the space.
if test x-L = "$p" ||
test x-R = "$p"; then
prev=$p
continue
fi
# Expand the sysroot to ease extracting the directories later.
if test -z "$prev"; then
case $p in
-L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
-R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
-l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
esac
fi
case $p in
=*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
esac
if test no = "$pre_test_object_deps_done"; then
case $prev in
-L | -R)
# Internal compiler library paths should come after those
# provided the user. The postdeps already come after the
# user supplied libs so there is no need to process them.
if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
_LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
else
_LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
fi
;;
# The "-l" case would never come before the object being
# linked, so don't bother handling this case.
esac
else
if test -z "$_LT_TAGVAR(postdeps, $1)"; then
_LT_TAGVAR(postdeps, $1)=$prev$p
else
_LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
fi
fi
prev=
;;
*.lto.$objext) ;; # Ignore GCC LTO objects
*.$objext)
# This assumes that the test object file only shows up
# once in the compiler output.
if test "$p" = "conftest.$objext"; then
pre_test_object_deps_done=yes
continue
fi
if test no = "$pre_test_object_deps_done"; then
if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
_LT_TAGVAR(predep_objects, $1)=$p
else
_LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
fi
else
if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
_LT_TAGVAR(postdep_objects, $1)=$p
else
_LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
fi
fi
;;
*) ;; # Ignore the rest.
esac
done
# Clean up.
rm -f a.out a.exe
else
echo "libtool.m4: error: problem compiling $1 test program"
fi
$RM -f confest.$objext
CFLAGS=$_lt_libdeps_save_CFLAGS
# PORTME: override above test on systems where it is broken
m4_if([$1], [CXX],
[case $host_os in
interix[[3-9]]*)
# Interix 3.5 installs completely hosed .la files for C++, so rather than
# hack all around it, let's just trust "g++" to DTRT.
_LT_TAGVAR(predep_objects,$1)=
_LT_TAGVAR(postdep_objects,$1)=
_LT_TAGVAR(postdeps,$1)=
;;
esac
])
case " $_LT_TAGVAR(postdeps, $1) " in
*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
esac
_LT_TAGVAR(compiler_lib_search_dirs, $1)=
if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
_LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
fi
_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
[The directories searched by this compiler when creating a shared library])
_LT_TAGDECL([], [predep_objects], [1],
[Dependencies to place before and after the objects being linked to
create a shared library])
_LT_TAGDECL([], [postdep_objects], [1])
_LT_TAGDECL([], [predeps], [1])
_LT_TAGDECL([], [postdeps], [1])
_LT_TAGDECL([], [compiler_lib_search_path], [1],
[The library search path used internally by the compiler when linking
a shared library])
])# _LT_SYS_HIDDEN_LIBDEPS
# _LT_LANG_F77_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for a Fortran 77 compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_F77_CONFIG],
[AC_LANG_PUSH(Fortran 77)
if test -z "$F77" || test no = "$F77"; then
_lt_disable_F77=yes
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(archive_expsym_cmds, $1)=
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=no
_LT_TAGVAR(inherit_rpath, $1)=no
_LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
_LT_TAGVAR(reload_flag, $1)=$reload_flag
_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
# Source file extension for f77 test sources.
ac_ext=f
# Object file extension for compiled f77 test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# No sense in running all these tests if we already determined that
# the F77 compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
if test yes != "$_lt_disable_F77"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
return
end
"
# Code to be used in simple link tests
lt_simple_link_test_code="\
program t
end
"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${F77-"f77"}
CFLAGS=$FFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
GCC=$G77
if test -n "$compiler"; then
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
if test ia64 != "$host_cpu"; then
case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
yes,aix,yes) ;; # shared object as lib.so file only
yes,svr4,*) ;; # shared object as lib.so archive member only
yes,*) enable_static=no ;; # shared object in lib.a archive as well
esac
fi
;;
esac
AC_MSG_RESULT([$enable_shared])
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
_LT_TAGVAR(GCC, $1)=$G77
_LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_SYS_DYNAMIC_LINKER($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
_LT_CONFIG($1)
fi # test -n "$compiler"
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
fi # test yes != "$_lt_disable_F77"
AC_LANG_POP
])# _LT_LANG_F77_CONFIG
# _LT_LANG_FC_CONFIG([TAG])
# -------------------------
# Ensure that the configuration variables for a Fortran compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_FC_CONFIG],
[AC_LANG_PUSH(Fortran)
if test -z "$FC" || test no = "$FC"; then
_lt_disable_FC=yes
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(allow_undefined_flag, $1)=
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(archive_expsym_cmds, $1)=
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=no
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(hardcode_libdir_separator, $1)=
_LT_TAGVAR(hardcode_minus_L, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=no
_LT_TAGVAR(inherit_rpath, $1)=no
_LT_TAGVAR(module_cmds, $1)=
_LT_TAGVAR(module_expsym_cmds, $1)=
_LT_TAGVAR(link_all_deplibs, $1)=unknown
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
_LT_TAGVAR(reload_flag, $1)=$reload_flag
_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
_LT_TAGVAR(no_undefined_flag, $1)=
_LT_TAGVAR(whole_archive_flag_spec, $1)=
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
# Source file extension for fc test sources.
ac_ext=${ac_fc_srcext-f}
# Object file extension for compiled fc test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# No sense in running all these tests if we already determined that
# the FC compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
if test yes != "$_lt_disable_FC"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
return
end
"
# Code to be used in simple link tests
lt_simple_link_test_code="\
program t
end
"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${FC-"f95"}
CFLAGS=$FCFLAGS
compiler=$CC
GCC=$ac_cv_fc_compiler_gnu
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
if test -n "$compiler"; then
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
if test ia64 != "$host_cpu"; then
case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
yes,aix,yes) ;; # shared object as lib.so file only
yes,svr4,*) ;; # shared object as lib.so archive member only
yes,*) enable_static=no ;; # shared object in lib.a archive as well
esac
fi
;;
esac
AC_MSG_RESULT([$enable_shared])
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
_LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
_LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
_LT_SYS_HIDDEN_LIBDEPS($1)
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_SYS_DYNAMIC_LINKER($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
_LT_CONFIG($1)
fi # test -n "$compiler"
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
fi # test yes != "$_lt_disable_FC"
AC_LANG_POP
])# _LT_LANG_FC_CONFIG
# _LT_LANG_GCJ_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for the GNU Java Compiler compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_GCJ_CONFIG],
[AC_REQUIRE([LT_PROG_GCJ])dnl
AC_LANG_SAVE
# Source file extension for Java test sources.
ac_ext=java
# Object file extension for compiled Java test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# Code to be used in simple compile tests
lt_simple_compile_test_code="class foo {}"
# Code to be used in simple link tests
lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=yes
CC=${GCJ-"gcj"}
CFLAGS=$GCJFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_TAGVAR(LD, $1)=$LD
_LT_CC_BASENAME([$compiler])
# GCJ did not exist at the time GCC didn't implicitly link libc in.
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
_LT_TAGVAR(reload_flag, $1)=$reload_flag
_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
if test -n "$compiler"; then
_LT_COMPILER_NO_RTTI($1)
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
_LT_CONFIG($1)
fi
AC_LANG_RESTORE
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
])# _LT_LANG_GCJ_CONFIG
# _LT_LANG_GO_CONFIG([TAG])
# --------------------------
# Ensure that the configuration variables for the GNU Go compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_GO_CONFIG],
[AC_REQUIRE([LT_PROG_GO])dnl
AC_LANG_SAVE
# Source file extension for Go test sources.
ac_ext=go
# Object file extension for compiled Go test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# Code to be used in simple compile tests
lt_simple_compile_test_code="package main; func main() { }"
# Code to be used in simple link tests
lt_simple_link_test_code='package main; func main() { }'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=yes
CC=${GOC-"gccgo"}
CFLAGS=$GOFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_TAGVAR(LD, $1)=$LD
_LT_CC_BASENAME([$compiler])
# Go did not exist at the time GCC didn't implicitly link libc in.
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
_LT_TAGVAR(reload_flag, $1)=$reload_flag
_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
## the running order or otherwise move them around unless you know exactly
## what you are doing...
if test -n "$compiler"; then
_LT_COMPILER_NO_RTTI($1)
_LT_COMPILER_PIC($1)
_LT_COMPILER_C_O($1)
_LT_COMPILER_FILE_LOCKS($1)
_LT_LINKER_SHLIBS($1)
_LT_LINKER_HARDCODE_LIBPATH($1)
_LT_CONFIG($1)
fi
AC_LANG_RESTORE
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
])# _LT_LANG_GO_CONFIG
# _LT_LANG_RC_CONFIG([TAG])
# -------------------------
# Ensure that the configuration variables for the Windows resource compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_RC_CONFIG],
[AC_REQUIRE([LT_PROG_RC])dnl
AC_LANG_SAVE
# Source file extension for RC test sources.
ac_ext=rc
# Object file extension for compiled RC test sources.
objext=o
_LT_TAGVAR(objext, $1)=$objext
# Code to be used in simple compile tests
lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
# Code to be used in simple link tests
lt_simple_link_test_code=$lt_simple_compile_test_code
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
# save warnings/boilerplate of simple test code
_LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=
CC=${RC-"windres"}
CFLAGS=
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
_LT_CC_BASENAME([$compiler])
_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
if test -n "$compiler"; then
:
_LT_CONFIG($1)
fi
GCC=$lt_save_GCC
AC_LANG_RESTORE
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
])# _LT_LANG_RC_CONFIG
# LT_PROG_GCJ
# -----------
AC_DEFUN([LT_PROG_GCJ],
[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
[m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
[AC_CHECK_TOOL(GCJ, gcj,)
test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
AC_SUBST(GCJFLAGS)])])[]dnl
])
# Old name:
AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
# LT_PROG_GO
# ----------
AC_DEFUN([LT_PROG_GO],
[AC_CHECK_TOOL(GOC, gccgo,)
])
# LT_PROG_RC
# ----------
AC_DEFUN([LT_PROG_RC],
[AC_CHECK_TOOL(RC, windres,)
])
# Old name:
AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([LT_AC_PROG_RC], [])
# _LT_DECL_EGREP
# --------------
# If we don't have a new enough Autoconf to choose the best grep
# available, choose the one first in the user's PATH.
m4_defun([_LT_DECL_EGREP],
[AC_REQUIRE([AC_PROG_EGREP])dnl
AC_REQUIRE([AC_PROG_FGREP])dnl
test -z "$GREP" && GREP=grep
_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
_LT_DECL([], [EGREP], [1], [An ERE matcher])
_LT_DECL([], [FGREP], [1], [A literal string matcher])
dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
AC_SUBST([GREP])
])
# _LT_DECL_OBJDUMP
# --------------
# If we don't have a new enough Autoconf to choose the best objdump
# available, choose the one first in the user's PATH.
m4_defun([_LT_DECL_OBJDUMP],
[AC_CHECK_TOOL(OBJDUMP, objdump, false)
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
AC_SUBST([OBJDUMP])
])
# _LT_DECL_DLLTOOL
# ----------------
# Ensure DLLTOOL variable is set.
m4_defun([_LT_DECL_DLLTOOL],
[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
AC_SUBST([DLLTOOL])
])
# _LT_DECL_SED
# ------------
# Check for a fully-functional sed program, that truncates
# as few characters as possible. Prefer GNU sed if found.
m4_defun([_LT_DECL_SED],
[AC_PROG_SED
test -z "$SED" && SED=sed
Xsed="$SED -e 1s/^X//"
_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
[Sed that helps us avoid accidentally triggering echo(1) options like -n])
])# _LT_DECL_SED
m4_ifndef([AC_PROG_SED], [
############################################################
# NOTE: This macro has been submitted for inclusion into #
# GNU Autoconf as AC_PROG_SED. When it is available in #
# a released version of Autoconf we should remove this #
# macro and use it instead. #
############################################################
m4_defun([AC_PROG_SED],
[AC_MSG_CHECKING([for a sed that does not truncate output])
AC_CACHE_VAL(lt_cv_path_SED,
[# Loop through the user's path and test for sed and gsed.
# Then use that list of sed's as ones to test for truncation.
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for lt_ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
fi
done
done
done
IFS=$as_save_IFS
lt_ac_max=0
lt_ac_count=0
# Add /usr/xpg4/bin/sed as it is typically found on Solaris
# along with /bin/sed that truncates output.
for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
test ! -f "$lt_ac_sed" && continue
cat /dev/null > conftest.in
lt_ac_count=0
echo $ECHO_N "0123456789$ECHO_C" >conftest.in
# Check for GNU sed and select it if it is found.
if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
lt_cv_path_SED=$lt_ac_sed
break
fi
while true; do
cat conftest.in conftest.in >conftest.tmp
mv conftest.tmp conftest.in
cp conftest.in conftest.nl
echo >>conftest.nl
$lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
cmp -s conftest.out conftest.nl || break
# 10000 chars as input seems more than enough
test 10 -lt "$lt_ac_count" && break
lt_ac_count=`expr $lt_ac_count + 1`
if test "$lt_ac_count" -gt "$lt_ac_max"; then
lt_ac_max=$lt_ac_count
lt_cv_path_SED=$lt_ac_sed
fi
done
done
])
SED=$lt_cv_path_SED
AC_SUBST([SED])
AC_MSG_RESULT([$SED])
])#AC_PROG_SED
])#m4_ifndef
# Old name:
AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([LT_AC_PROG_SED], [])
# _LT_CHECK_SHELL_FEATURES
# ------------------------
# Find out whether the shell is Bourne or XSI compatible,
# or has some other useful features.
m4_defun([_LT_CHECK_SHELL_FEATURES],
[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
lt_unset=unset
else
lt_unset=false
fi
_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
# test EBCDIC or ASCII
case `echo X|tr X '\101'` in
A) # ASCII based system
# \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
lt_SP2NL='tr \040 \012'
lt_NL2SP='tr \015\012 \040\040'
;;
*) # EBCDIC based system
lt_SP2NL='tr \100 \n'
lt_NL2SP='tr \r\n \100\100'
;;
esac
_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
])# _LT_CHECK_SHELL_FEATURES
# _LT_PATH_CONVERSION_FUNCTIONS
# -----------------------------
# Determine what file name conversion functions should be used by
# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
# for certain cross-compile configurations and native mingw.
m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
AC_MSG_CHECKING([how to convert $build file names to $host format])
AC_CACHE_VAL(lt_cv_to_host_file_cmd,
[case $host in
*-*-mingw* )
case $build in
*-*-mingw* ) # actually msys
lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
;;
*-*-cygwin* )
lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
;;
* ) # otherwise, assume *nix
lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
;;
esac
;;
*-*-cygwin* )
case $build in
*-*-mingw* ) # actually msys
lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
;;
*-*-cygwin* )
lt_cv_to_host_file_cmd=func_convert_file_noop
;;
* ) # otherwise, assume *nix
lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
;;
esac
;;
* ) # unhandled hosts (and "normal" native builds)
lt_cv_to_host_file_cmd=func_convert_file_noop
;;
esac
])
to_host_file_cmd=$lt_cv_to_host_file_cmd
AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
[0], [convert $build file names to $host format])dnl
AC_MSG_CHECKING([how to convert $build file names to toolchain format])
AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
[#assume ordinary cross tools, or native build.
lt_cv_to_tool_file_cmd=func_convert_file_noop
case $host in
*-*-mingw* )
case $build in
*-*-mingw* ) # actually msys
lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
;;
esac
;;
esac
])
to_tool_file_cmd=$lt_cv_to_tool_file_cmd
AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
[0], [convert $build files to toolchain format])dnl
])# _LT_PATH_CONVERSION_FUNCTIONS
libspatialite-5.1.0/m4/ltoptions.m4 0000644 0001750 0001750 00000034262 14463127014 014112 0000000 0000000 # Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])
libspatialite-5.1.0/m4/ltsugar.m4 0000644 0001750 0001750 00000010440 14463127014 013530 0000000 0000000 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59, which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])
libspatialite-5.1.0/m4/ltversion.m4 0000644 0001750 0001750 00000001273 14463127014 014100 0000000 0000000 # ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4179 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
libspatialite-5.1.0/m4/lt~obsolete.m4 0000644 0001750 0001750 00000013774 14463127014 014436 0000000 0000000 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
libspatialite-5.1.0/src/ 0000755 0001750 0001750 00000000000 14463127115 012137 5 0000000 0000000 libspatialite-5.1.0/src/headers/ 0000755 0001750 0001750 00000000000 14463127115 013552 5 0000000 0000000 libspatialite-5.1.0/src/headers/spatialite/ 0000755 0001750 0001750 00000000000 14463127115 015711 5 0000000 0000000 libspatialite-5.1.0/src/headers/spatialite/gaiaconfig-msvc.h.in 0000644 0001750 0001750 00000003056 14463127014 021446 0000000 0000000 /* ./src/headers/spatialite/gaiaconfig-msvc.h.in - manually maintained */
/* Should be defined in order to enable GCP support. */
#undef ENABLE_GCP
/* Should be defined in order to enable GeoPackage support. */
#define ENABLE_GEOPACKAGE 1
/* Should be defined in order to enable LIBXML2 support. */
#define ENABLE_LIBXML2 1
/* Should be defined in order to enable RTTOPO support. */
#define ENABLE_RTTOPO 1
/* Should be defined in order to enable GEOS_370 support. */
#define GEOS_370 1
/* Should be defined in order to enable GEOS_ADVANCED support. */
#define GEOS_ADVANCED 1
/* Should be defined in order to fully disable GEOS non-thread-safe API. */
/* #undef GEOS_ONLY_REENTRANT */
/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
#define GEOS_REENTRANT 1
/* Should be defined in order to disable EPSG full support. */
#undef OMIT_EPSG
/* Should be defined in order to disable FREEXL support. */
#undef OMIT_FREEXL
/* Should be defined in order to disable GEOCALLBACKS support. */
#define OMIT_GEOCALLBACKS 1
/* Should be defined in order to disable GEOS support. */
#undef OMIT_GEOS
/* Should be defined in order to disable ICONV support. */
#undef OMIT_ICONV
/* Should be defined in order to disable KNN support. */
#undef OMIT_KNN
/* Should be defined in order to disable MATHSQL support. */
#undef OMIT_MATHSQL
/* Should be defined in order to disable PROJ.4 support. */
#undef OMIT_PROJ
/* Should be defined in order to enable PROJ.6 support. */
#define PROJ_NEW 1
/* the Version of this package */
#undef SPATIALITE_VERSION
libspatialite-5.1.0/src/headers/spatialite/gaiaconfig.h.in 0000644 0001750 0001750 00000003542 14463127014 020500 0000000 0000000 /* ./src/headers/spatialite/gaiaconfig.h.in - manually maintained */
/* Should be defined in order to enable GCP support. */
#undef ENABLE_GCP
/* Should be defined in order to enable GeoPackage support. */
#undef ENABLE_GEOPACKAGE
/* Should be defined in order to enable LIBXML2 support. */
#undef ENABLE_LIBXML2
/* Should be defined in order to enable MiniZIP support. */
#undef ENABLE_MINIZIP
/* Should be defined in order to enable RTTOPO support. */
#undef ENABLE_RTTOPO
/* Should be defined in order to enable GEOS_370 support. */
#undef GEOS_370
/* Should be defined in order to enable GEOS_3100 support. */
#undef GEOS_3100
/* Should be defined in order to enable GEOS_3110 support. */
#undef GEOS_3110
/* Should be defined in order to enable GEOS_ADVANCED support. */
#undef GEOS_ADVANCED
/* Should be defined in order to fully disable GEOS non-thread-safe API. */
#undef GEOS_ONLY_REENTRANT
/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
#undef GEOS_REENTRANT
/* Should be defined in order to disable EPSG full support. */
#undef OMIT_EPSG
/* Should be defined in order to disable FREEXL support. */
#undef OMIT_FREEXL
/* Should be defined in order to disable GEOCALLBACKS support. */
#undef OMIT_GEOCALLBACKS
/* Should be defined in order to disable GEOS support. */
#undef OMIT_GEOS
/* Should be defined in order to disable ICONV support. */
#undef OMIT_ICONV
/* Should be defined in order to disable KNN support. */
#undef OMIT_KNN
/* Should be defined in order to disable MATHSQL support. */
#undef OMIT_MATHSQL
/* Should be defined in order to disable PROJ.4 support. */
#undef OMIT_PROJ
/* Should be defined in order to enable PROJ.6 support. */
#undef PROJ_NEW
/* Should contain a text-string describing the intended target CPU */
#undef SPATIALITE_TARGET_CPU
/* the Version of this package */
#undef SPATIALITE_VERSION
libspatialite-5.1.0/src/headers/spatialite/gaiaconfig.h 0000644 0001750 0001750 00000004073 14463127014 020073 0000000 0000000 /* ./src/headers/spatialite/gaiaconfig.h. Generated from gaiaconfig.h.in by configure. */
/* ./src/headers/spatialite/gaiaconfig.h.in - manually maintained */
/* Should be defined in order to enable GCP support. */
#define ENABLE_GCP 1
/* Should be defined in order to enable GeoPackage support. */
#define ENABLE_GEOPACKAGE 1
/* Should be defined in order to enable LIBXML2 support. */
#define ENABLE_LIBXML2 1
/* Should be defined in order to enable MiniZIP support. */
#define ENABLE_MINIZIP 1
/* Should be defined in order to enable RTTOPO support. */
#define ENABLE_RTTOPO 1
/* Should be defined in order to enable GEOS_370 support. */
#define GEOS_370 1
/* Should be defined in order to enable GEOS_3100 support. */
/* #undef GEOS_3100 */
/* Should be defined in order to enable GEOS_3110 support. */
/* #undef GEOS_3110 */
/* Should be defined in order to enable GEOS_ADVANCED support. */
#define GEOS_ADVANCED 1
/* Should be defined in order to fully disable GEOS non-thread-safe API. */
/* #undef GEOS_ONLY_REENTRANT */
/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
#define GEOS_REENTRANT 1
/* Should be defined in order to disable EPSG full support. */
/* #undef OMIT_EPSG */
/* Should be defined in order to disable FREEXL support. */
/* #undef OMIT_FREEXL */
/* Should be defined in order to disable GEOCALLBACKS support. */
/* #undef OMIT_GEOCALLBACKS */
/* Should be defined in order to disable GEOS support. */
/* #undef OMIT_GEOS */
/* Should be defined in order to disable ICONV support. */
/* #undef OMIT_ICONV */
/* Should be defined in order to disable KNN support. */
/* #undef OMIT_KNN */
/* Should be defined in order to disable MATHSQL support. */
/* #undef OMIT_MATHSQL */
/* Should be defined in order to disable PROJ.4 support. */
/* #undef OMIT_PROJ */
/* Should be defined in order to enable PROJ.6 support. */
#define PROJ_NEW 1
/* Should contain a text-string describing the intended target CPU */
#define SPATIALITE_TARGET_CPU "x86_64-redhat-linux"
/* the Version of this package */
#define SPATIALITE_VERSION "5.1.0"
libspatialite-5.1.0/src/headers/spatialite/gaiaconfig-msvc.h 0000644 0001750 0001750 00000003312 14463127014 021034 0000000 0000000 /* ./src/headers/spatialite/gaiaconfig-msvc.h. Generated from gaiaconfig-msvc.h.in by configure. */
/* ./src/headers/spatialite/gaiaconfig-msvc.h.in - manually maintained */
/* Should be defined in order to enable GCP support. */
#define ENABLE_GCP 1
/* Should be defined in order to enable GeoPackage support. */
#define ENABLE_GEOPACKAGE 1
/* Should be defined in order to enable LIBXML2 support. */
#define ENABLE_LIBXML2 1
/* Should be defined in order to enable RTTOPO support. */
#define ENABLE_RTTOPO 1
/* Should be defined in order to enable GEOS_370 support. */
#define GEOS_370 1
/* Should be defined in order to enable GEOS_ADVANCED support. */
#define GEOS_ADVANCED 1
/* Should be defined in order to fully disable GEOS non-thread-safe API. */
/* #undef GEOS_ONLY_REENTRANT */
/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
#define GEOS_REENTRANT 1
/* Should be defined in order to disable EPSG full support. */
/* #undef OMIT_EPSG */
/* Should be defined in order to disable FREEXL support. */
/* #undef OMIT_FREEXL */
/* Should be defined in order to disable GEOCALLBACKS support. */
#define OMIT_GEOCALLBACKS 1
/* Should be defined in order to disable GEOS support. */
/* #undef OMIT_GEOS */
/* Should be defined in order to disable ICONV support. */
/* #undef OMIT_ICONV */
/* Should be defined in order to disable KNN support. */
/* #undef OMIT_KNN */
/* Should be defined in order to disable MATHSQL support. */
/* #undef OMIT_MATHSQL */
/* Should be defined in order to disable PROJ.4 support. */
/* #undef OMIT_PROJ */
/* Should be defined in order to enable PROJ.6 support. */
#define PROJ_NEW 1
/* the Version of this package */
#define SPATIALITE_VERSION "5.1.0"
libspatialite-5.1.0/src/headers/spatialite/gaiaexif.h 0000644 0001750 0001750 00000046670 14463127014 017572 0000000 0000000 /*
gaiaexif.h -- Gaia common EXIF Metadata reading functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaiaexif.h
EXIF/image: supporting functions and constants
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef DLL_EXPORT
#define GAIAEXIF_DECLARE __declspec(dllexport)
#else
#define GAIAEXIF_DECLARE extern
#endif
#endif
#ifndef _GAIAEXIF_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIAEXIF_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constants used for BLOB value types */
/** generic hexadecimal BLOB */
#define GAIA_HEX_BLOB 0
/** this BLOB does actually contain a GIF image */
#define GAIA_GIF_BLOB 1
/** this BLOB does actually containt a PNG image */
#define GAIA_PNG_BLOB 2
/** this BLOB does actually contain a generic JPEG image */
#define GAIA_JPEG_BLOB 3
/** this BLOB does actually contain a JPEG-EXIF image */
#define GAIA_EXIF_BLOB 4
/** this BLOB does actually contain a JPEG-EXIF image including GPS data */
#define GAIA_EXIF_GPS_BLOB 5
/** this BLOB does actually contain a ZIP compressed file */
#define GAIA_ZIP_BLOB 6
/** this BLOB does actually contain a PDF document */
#define GAIA_PDF_BLOB 7
/** this BLOB does actually contain a SpatiaLite Geometry (not compressed) */
#define GAIA_GEOMETRY_BLOB 8
/** this BLOB does actually contain a SpatiaLite Geometry (compressed) */
#define GAIA_COMPRESSED_GEOMETRY_BLOB 9
/** this BLOB does actually contain a TIFF image */
#define GAIA_TIFF_BLOB 10
/** this BLOB does actually contain a WebP image */
#define GAIA_WEBP_BLOB 11
/** this BLOB does actually contain a JP2 (Jpeg2000) image */
#define GAIA_JP2_BLOB 12
/** this BLOB does actually contain a SpatiaLite XmlBLOB */
#define GAIA_XML_BLOB 13
/** this BLOB does actually contain a GPKG Geometry */
#define GAIA_GPB_BLOB 14
/** this BLOB does actually contain a SpatiaLite TinyPoint */
#define GAIA_TINYPOINT_BLOB 15
/* constants used for EXIF value types */
/** unrecognized EXIF value */
#define GAIA_EXIF_NONE 0
/** EXIF value of the BYTE type */
#define GAIA_EXIF_BYTE 1
/** EXIF value of the SHORT type */
#define GAIA_EXIF_SHORT 2
/** EXIF value of the STRING type */
#define GAIA_EXIF_STRING 3
/** EXIF value of the LONG type */
#define GAIA_EXIF_LONG 4
/** EXIF value of the RATIONAL type */
#define GAIA_EXIF_RATIONAL 5
/** EXIF value of the SLONG type */
#define GAIA_EXIF_SLONG 9
/** EXIF value of the SRATIONAL type */
#define GAIA_EXIF_SRATIONAL 10
/**
Container for an EXIF tag
*/
typedef struct gaiaExifTagStruct
{
/* an EXIF TAG */
/** GPS data included (0/1) */
char Gps;
/** EXIF tag ID */
unsigned short TagId;
/** EXIF value type */
unsigned short Type;
/** number of values */
unsigned short Count;
/** tag offset [big- little-endian encoded] */
unsigned char TagOffset[4];
/** array of BYTE values */
unsigned char *ByteValue;
/** array of STRING values */
char *StringValue;
/** array of SHORT values */
unsigned short *ShortValues;
/** array of LONG values ] */
unsigned int *LongValues;
/** array of RATIONAL values [numerators] */
unsigned int *LongRationals1;
/** array of RATIONAL values [denominators] */
unsigned int *LongRationals2;
/** array of Signed SHORT values */
short *SignedShortValues;
/** array of Signed LONG values */
int *SignedLongValues;
/** array of Signed RATIONAL values [numerators] */
int *SignedLongRationals1;
/** array of Signed RATIONAL values [denominators] */
int *SignedLongRationals2;
/** array of FLOAT values */
float *FloatValues;
/** array of DOUBLE values */
double *DoubleValues;
/** pointer to next item into the linked list */
struct gaiaExifTagStruct *Next;
} gaiaExifTag;
/**
Typedef for EXIF tag structure.
\sa gaiaExifTagStruct
*/
typedef gaiaExifTag *gaiaExifTagPtr;
/**
Container for a list of EXIF tags
*/
typedef struct gaiaExifTagListStruct
{
/* an EXIF TAG LIST */
/** pointer to first item into the linked list */
gaiaExifTagPtr First;
/** pointer to the last item into the linked list */
gaiaExifTagPtr Last;
/** number of items */
int NumTags;
/** an array of pointers to items */
gaiaExifTagPtr *TagsArray;
} gaiaExifTagList;
/**
Typedef for EXIF tag structure
\sa gaiaExifTagListStruct
*/
typedef gaiaExifTagList *gaiaExifTagListPtr;
/* function prototipes */
/**
Creates a list of EXIF tags by parsing a BLOB of the JPEG-EXIF type
\param blob the BLOB to be parsed
\param size the BLOB size (in bytes)
\return a list of EXIF tags: or NULL if any error is encountered
\sa gaiaExifTagsFree
\note you must explicitly destroy the list when it's any longer used.
*/
GAIAEXIF_DECLARE gaiaExifTagListPtr gaiaGetExifTags (const unsigned char
*blob, int size);
/**
Destroy a list of EXIF tags
\param tag_list the list to be destroied
\sa gaiaGetExifTags
\note the pointer passed to this function must be one returned by a
previous call to gaiaGetExifTags
*/
GAIAEXIF_DECLARE void gaiaExifTagsFree (gaiaExifTagListPtr tag_list);
/**
Return the total number of EXIF tags into the list
\param tag_list pointer to an EXIF tag list.
\return the EXIF tag count.
\sa gaiaGetExifTags, gaiaExifTagsFree
*/
GAIAEXIF_DECLARE int gaiaGetExifTagsCount (gaiaExifTagListPtr tag_list);
/**
Retrieves an EXIF tag by its relative position into the list
\param tag_list pointer to an EXIF tag list.
\param pos relative item position [first item is 0]
\return a pointer to the corresponding EXIF tag: NULL if not found
\sa gaiaGetExifTags, gaiaExifTagsFree, gaiaExifTagsCount
*/
GAIAEXIF_DECLARE gaiaExifTagPtr gaiaGetExifTagByPos (gaiaExifTagListPtr
tag_list,
const int pos);
/**
Return the total number of EXIF tags into the list
\param tag_list pointer to an EXIF tag list.
\return the EXIF tag count.
\sa gaiaGetExifTags, gaiaExifTagsFree
*/
GAIAEXIF_DECLARE int gaiaGetExifTagsCount (gaiaExifTagListPtr tag_list);
/**
Retrieves an EXIF tag by its Tag ID
\param tag_list pointer to an EXIF tag list.
\param tag_id the Tag ID to be found
\return a pointer to the corresponding EXIF tag: NULL if not found
\sa gaiaGetExifTags, gaiaExifTagsFree
*/
GAIAEXIF_DECLARE gaiaExifTagPtr gaiaGetExifTagById (const
gaiaExifTagListPtr
tag_list,
const unsigned short
tag_id);
/**
Retrieves an EXIF-GPS tag by its Tag ID
\param tag_list pointer to an EXIF tag list.
\param tag_id the GPS Tag ID to be found
\return a pointer to the corresponding EXIF tag: NULL if not found
\sa gaiaGetExifTags, gaiaExifTagsFree
*/
GAIAEXIF_DECLARE gaiaExifTagPtr gaiaGetExifGpsTagById (const
gaiaExifTagListPtr
tag_list,
const unsigned
short tag_id);
/**
Retrieves an EXIF tag by its name
\param tag_list pointer to an EXIF tag list.
\param tag_name the Tag Name to be found
\return a pointer to the corresponding EXIF tag: NULL if not found
\sa gaiaGetExifTags, gaiaExifTagsFree
*/
GAIAEXIF_DECLARE gaiaExifTagPtr gaiaGetExifTagByName (const
gaiaExifTagListPtr
tag_list,
const char *tag_name);
/**
Return the Tag ID from an EXIF tag
\param tag pointer to an EXIF tag
\return the Tag ID
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE unsigned short gaiaExifTagGetId (const gaiaExifTagPtr tag);
/**
Return the Tag Name from an EXIF tag
\param tag pointer to an EXIF tag
\param tag_name receiving buffer: the Tag Name will be copied here
\param len length of the receiving buffer
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE void gaiaExifTagGetName (const gaiaExifTagPtr tag,
char *tag_name, int len);
/**
Checks if an EXIF tag actually is an EXIF-GPS tag
\param tag pointer to an EXIF tag
\return 0 if false: any other value if true
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE int gaiaIsExifGpsTag (const gaiaExifTagPtr tag);
/**
Return the value type for an EXIF tag
\param tag pointer to an EXIF tag
\return the value type: one of GAIA_EXIF_NONE, GAIA_EXIF_BYTE,
GAIA_EXIF_SHORT, GAIA_EXIF_STRING, GAIA_EXIF_LONG, GAIA_EXIF_RATIONAL,
GAIA_EXIF_SLONG, GAIA_EXIF_SRATIONAL
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE unsigned short gaiaExifTagGetValueType (const
gaiaExifTagPtr
tag);
/**
Return the total count of values from an EXIF tag
\param tag pointer to an EXIF tag
\return the number of available values
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE unsigned short gaiaExifTagGetNumValues (const
gaiaExifTagPtr
tag);
/**
Return a BYTE value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the BYTE value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE unsigned char gaiaExifTagGetByteValue (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a STRING value from an EXIF tag
\param tag pointer to an EXIF tag.
\param str receiving buffer: the STRING value will be copied here.
\param len length of the receiving buffer
\param ok on completion will contain 0 on failure: any other value on success.
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE void gaiaExifTagGetStringValue (const gaiaExifTagPtr tag,
char *str, int len,
int *ok);
/**
Return a SHORT value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the SHORT value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE unsigned short gaiaExifTagGetShortValue (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a LONG value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the LONG value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE unsigned int gaiaExifTagGetLongValue (const
gaiaExifTagPtr tag,
const int ind,
int *ok);
/**
Return a RATIONAL [numerator] value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the RATIONAL [numerator] value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE unsigned int gaiaExifTagGetRational1Value (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a RATIONAL [denominator] value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the RATIONAL [denominator] value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE unsigned int gaiaExifTagGetRational2Value (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a RATIONAL value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the RATIONAL value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE double gaiaExifTagGetRationalValue (const gaiaExifTagPtr
tag, const int ind,
int *ok);
/**
Return a Signed SHORT value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the Signed SHORT value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE short gaiaExifTagGetSignedShortValue (const
gaiaExifTagPtr tag,
const int ind,
int *ok);
/**
Return a Signed LONG value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the Signed LONG value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE int gaiaExifTagGetSignedLongValue (const gaiaExifTagPtr
tag, const int ind,
int *ok);
/**
Return a SRATIONAL [numerator] value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the SRATIONAL [numerator] value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE int gaiaExifTagGetSignedRational1Value (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a SRATIONAL [denominator] value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the SRATIONAL [denominator] value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE int gaiaExifTagGetSignedRational2Value (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a Signed RATIONAL value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the Signed RATIONAL value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE double gaiaExifTagGetSignedRationalValue (const
gaiaExifTagPtr
tag,
const int ind,
int *ok);
/**
Return a FLOAT value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the FLOAT value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE float gaiaExifTagGetFloatValue (const gaiaExifTagPtr tag,
const int ind, int *ok);
/**
Return a DOUBLE value from an EXIF tag
\param tag pointer to an EXIF tag.
\param ind value index [first value has index 0].
\param ok on completion will contain 0 on failure: any other value on success.
\return the DOUBLE value
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaExifTagGetValueType, gaiaExifTagGetNumValues
*/
GAIAEXIF_DECLARE double gaiaExifTagGetDoubleValue (const gaiaExifTagPtr
tag, const int ind,
int *ok);
/**
Return a human readable description from an EXIF tag
\param tag pointer to an EXIF tag.
\param str receiving buffer: the STRING value will be copied here.
\param len length of the receiving buffer
\param ok on completion will contain 0 on failure: any other value on success.
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName
*/
GAIAEXIF_DECLARE void gaiaExifTagGetHumanReadable (const gaiaExifTagPtr
tag, char *str,
int len, int *ok);
/**
Attempts to guess the actual content-type of some BLOB
\param blob the BLOB to be parsed
\param size length of the BLOB (in bytes)
\return the BLOB type: one of GAIA_HEX_BLOB, GAIA_GIF_BLOB, GAIA_PNG_BLOB,
GAIA_JPEG_BLOB, GAIA_EXIF_BLOB, GAIA_EXIF_GPS_BLOB, GAIA_ZIP_BLOB,
GAIA_PDF_BLOB, GAIA_GEOMETRY_BLOB, GAIA_TIFF_BLOB, GAIA_WEBP_BLOB,
GAIA_JP2_BLOB, GAIA_XML_BLOB, GAIA_GPB_BLOB
*/
GAIAEXIF_DECLARE int gaiaGuessBlobType (const unsigned char *blob,
int size);
/**
Return longitude and latitude from an EXIF-GPS tag
\param blob the BLOB to be parsed
\param size length of the BLOB (in bytes)
\param longitude on success will contain the longitude coordinate
\param latitude on success will contain the latitude coordinate
\return 0 on failure: any other value on success
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaIsExifGpsTag
*/
GAIAEXIF_DECLARE int gaiaGetGpsCoords (const unsigned char *blob,
int size, double *longitude,
double *latitude);
/**
Return a text string representing DMS coordinates from an EXIF-GPS tag
\param blob the BLOB to be parsed
\param size length of the BLOB (in bytes)
\param latlong receiving buffer: the text string will be copied here.
\param ll_size length of the receiving buffer
\return 0 on failure: any other value on success
\sa gaiaGetExifTagById, gaiaGetExifGpsTagById, gaiaGetExifTagByName,
gaiaIsExifGpsTag
*/
GAIAEXIF_DECLARE int gaiaGetGpsLatLong (const unsigned char *blob,
int size, char *latlong,
int ll_size);
#ifdef __cplusplus
}
#endif
#endif /* _GAIAEXIF_H */
libspatialite-5.1.0/src/headers/spatialite/gaiaaux.h 0000644 0001750 0001750 00000040334 14463127014 017423 0000000 0000000 /*
gaiaaux.h -- Gaia common utility functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaiaaux.h
Auxiliary/helper functions
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef DLL_EXPORT
#define GAIAAUX_DECLARE __declspec(dllexport)
#else
#define GAIAAUX_DECLARE extern
#endif
#endif
#ifndef _GAIAAUX_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIAAUX_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constants */
/** SQL single quoted string (text constant) */
#define GAIA_SQL_SINGLE_QUOTE 1001
/** SQL double quoted string (SQL name) */
#define GAIA_SQL_DOUBLE_QUOTE 1002
/* function prototypes */
/**
Retrieves the Locale Charset
\return the GNU ICONV name identifying the locale charset
*/
GAIAAUX_DECLARE const char *gaiaGetLocaleCharset (void);
/**
Converts a text string from one charset to another
\param buf the text string to be converted
\param fromCs the GNU ICONV name identifying the input charset
\param toCs the GNU ICONV name identifying the output charset
\return 0 on failure, any other value on success.
\note this function uses an internal buffer limited to 64KB;
so it's not safe passing extremely huge-sized text string.
*/
GAIAAUX_DECLARE int gaiaConvertCharset (char **buf, const char *fromCs,
const char *toCs);
/**
Creates a persistent UTF8 converter object
\param fromCS the GNU ICONV name identifying the input charset
\return the handle of the converter object, or NULL on failure
\sa gaiaFreeUTF8Converter
\note you must properly destroy the converter object
when it isn't any longer used.
*/
GAIAAUX_DECLARE void *gaiaCreateUTF8Converter (const char *fromCS);
/**
Destroys an UTF8 converter object
\param cvtCS the handle identifying the UTF8 convert object
(returned by a previous call to gaiaCreateUTF8Converter).
\sa gaiaCreateUTF8Converter
*/
GAIAAUX_DECLARE void gaiaFreeUTF8Converter (void *cvtCS);
/**
Converts a text string to UTF8
\param cvtCS the handle identifying the UTF8 convert object
(returned by a previous call to gaiaCreateUTF8Converter).
\param buf the input text string
\param len length (in bytes) of input string
\param err on completion will contain 0 on success, any other value on failure
\return the null-terminated UTF8 encoded string: NULL on failure
\sa gaiaCreateUTF8Converter, gaiaFreeUTF8Converter
\note this function can safely handle strings of arbitrary length,
and will return the converted string into a dynamically allocated buffer
created by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaConvertToUTF8 (void *cvtCS, const char *buf,
int len, int *err);
/**
Checks if a name is a reserved SQLite name
\param name the name to be checked
\return 0 if no: any other value if yes
\sa gaiaIsReservedSqlName, gaiaIllegalSqlName
*/
GAIAAUX_DECLARE int gaiaIsReservedSqliteName (const char *name);
/**
Checks if a name is a reserved SQL name
\param name the name to be checked
\return 0 if no: any other value if yes
\sa gaiaIsReservedSqliteName, gaiaIllegalSqlName
*/
GAIAAUX_DECLARE int gaiaIsReservedSqlName (const char *name);
/**
Checks if a name is an illegal SQL name
\param name the name to be checked
\return 0 if no: any other value if yes
\sa gaiaIsReservedSqliteName, gaiaIsReservedSqlName
*/
GAIAAUX_DECLARE int gaiaIllegalSqlName (const char *name);
/**
Properly formats an SQL text constant
\param value the text string to be formatted
\return the formatted string: NULL on failure
\sa gaiaQuotedSql, gaiaDequotedSql
\note this function simply is a convenience method corresponding to:
gaiaQuotedSQL(value, GAIA_SQL_SINGLE_QUOTE);
\remark passing a string like "Sant'Andrea" will return 'Sant''Andrea'
*/
GAIAAUX_DECLARE char *gaiaSingleQuotedSql (const char *value);
/**
Properly formats an SQL name
\param value the SQL name to be formatted
\return the formatted string: NULL on failure
\sa gaiaQuotedSql, gaiaDequotedSql
\note this function simply is a convenience method corresponding to:
gaiaQuotedSQL(value, GAIA_SQL_DOUBLE_QUOTE);
\remark passing a string like "Sant\"Andrea" will return "Sant""Andrea"
*/
GAIAAUX_DECLARE char *gaiaDoubleQuotedSql (const char *value);
/**
Properly formats an SQL generic string
\param value the string to be formatted
\param quote GAIA_SQL_SINGLE_QUOTE or GAIA_SQL_DOUBLE_QUOTE
\return the formatted string: NULL on failure
\sa gaiaSingleQuotedSql, gaiaDoubleQuotedSql, gaiaDequotedSql
\note this function can safely handle strings of arbitrary length,
and will return the formatted string into a dynamically allocated buffer
created by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaQuotedSql (const char *value, int quote);
/**
Properly formats an SQL generic string (dequoting)
\param value the string to be dequoted
\return the formatted string: NULL on failure
\sa gaiaSingleQuotedSql, gaiaDoubleQuotedSql, gaiaQuotedSql
\note this function can safely handle strings of arbitrary length,
and will return the formatted string into a dynamically allocated buffer
created by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaDequotedSql (const char *value);
/*
/ DEPRECATED FUNCTION: gaiaCleanSqlString()
/ this function must not be used for any new project
/ it's still maintained for backward compatibility,
/ but will be probably removed in future versions
*/
/**
deprecated function
\param value the string to be formatted
\sa gaiaQuotedSql
\note this function is still supported simply for backward compatibility.
it's intrinsically unsafe (passing huge strings potentially leads to
buffer overflows) and you are strongly encouraged to use gaiaQuotedSql()
as a safest replacement.
*/
GAIAAUX_DECLARE void gaiaCleanSqlString (char *value);
/**
SQL log: statement start
\param sqlite handle of the current DB connection
\param user_agent name of the invoking application, e.g. "spatialite_gui" or "spatialite CLI"
\param utf8Sql the SQL statement bein executed
\param sqllog_pk after completion this variable will contain the value
of the Primary Key identifying the corresponding Log event
\sa gaiaUpdateSqlLog
\note this function inserts an \b event into the SQL Log, and
is expected to be invoked immediately \b before executing the SQL
statement itself.
*/
GAIAAUX_DECLARE void gaiaInsertIntoSqlLog (sqlite3 * sqlite,
const char *user_agent,
const char *utf8Sql,
sqlite3_int64 * sqllog_pk);
/**
SQL log: statement start
\param sqlite handle of the current DB connection
\param sqllog_pk the Primary Key identifying the corresponding Log event.
\n expected to be exactely the same returned by the most recent call to gaiaInsertIntoSqlLog()
\param success expected to be TRUE if the SQL statement was successfully executed.
\param errMsg expected to be the error message returned by SQLite on failure, NULL on success.
\sa gaiaInsertIntoSqlLog
\note this function completes an \b event inserted into the SQL Log, and
is expected to be invoked immediately \b after executing the SQL
statement itself.
*/
GAIAAUX_DECLARE void gaiaUpdateSqlLog (sqlite3 * sqlite,
sqlite3_int64 sqllog_pk,
int success, const char *errMsg);
/**
Creates a persistent MD5 checksum object
\return the handle of an MD5 checksum object, or NULL on failure
\sa gaiaFreeMD5Checksum, gaiaUpdateMD5Checksum, gaiaFinalizeMD5Checksum
\note you must properly destroy the MD5 object
when it isn't any longer used.
*/
GAIAAUX_DECLARE void *gaiaCreateMD5Checksum (void);
/**
Destroys an MD5 checksum object
\param md5 the handle of the MD5 checksum object (returned by
a previous call to gaiaCreateMD5Checksum).
\sa gaiaCreateMD5Checksum
*/
GAIAAUX_DECLARE void gaiaFreeMD5Checksum (void *md5);
/**
Updates an MD5 checksum object
\param md5 the handle of the MD5 checksum object (returned by
a previous call to gaiaCreateMD5Checksum).
\param blob an arbitrary sequence of binary data
\param blob_size the length (in bytes) of the binary data
\sa gaiaCreateMD5Checksum, gaiaFreeMD5Checksum, gaiaFinalizeMD5Checksum
\note you can repeatedly invoke gaiaUpdateMD5Checksum more than a single
time and always using the same MD5 object.
In this case the final MD5 checksum returned by gaiaGetMD5Checsum will be
the total checksum for any data processed by the MD5 object since its
initialization.
*/
GAIAAUX_DECLARE void gaiaUpdateMD5Checksum (void *md5,
const unsigned char *blob,
int blob_len);
/**
Return an MD5 checksum value
\param md5 the handle of the MD5 checksum object (returned by
a previous call to gaiaCreateMD5Checksum).
\return an hexadecimal text string representing the MD checksum:
NULL on failure
\sa gaiaCreateMD5Checksum, gaiaUpdateMD5Checksum, gaiaFreeMD5Checksum
\note this function will return the MD5 checksum into a dynamically allocated
buffer created by malloc().
You are required to explicitly free() any string returned by this function.
\note gaiaFinalizeMD5Checksum will implicitly reset the MD5 object to its
initial state.
*/
GAIAAUX_DECLARE char *gaiaFinalizeMD5Checksum (void *md5);
/**
Return longitude and latitude angles from a DMS string
\param dms a text string representing a valid DMS (Degrees/Minutes/Seconds)
expression.
\param longitude on completion this variable will contain the longitude angle
expressed in Decimal Degrees.
\param latitude on completion this variable will contain the latitude angle
expressed in Decimal Degrees.
\return ZERO (FALSE) on failure, any other different value (TRUE) on success.
\sa gaiaConvertToDMS
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE int gaiaParseDMS (const char *dms, double *longitude,
double *latitude);
/**
Return a DMS string - extended
\param longitude the angle of longitude expressed in Decimal Degrees.
\param latitude the angle of latitude expressed in Decimal Degrees.
\param decimal_digits how many decimal digits must be preserved for
representing Seconds.
\return the corresponding DMS (Degrees/Minutes/Seconds) text string,
or NULL on failure
\sa gaiaLongitudeFromDMS, gaiaLatitudeFromDMS
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaConvertToDMSex (double longitude, double latitude,
int decimal_digits);
/**
Return a DMS string
\param longitude the angle of longitude expressed in Decimal Degrees.
\param latitude the angle of latitude expressed in Decimal Degrees.
\return the corresponding DMS (Degrees/Minutes/Seconds) text string,
or NULL on failure
\sa gaiaConvertToDMSex
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
\note this functions simply defaults to gaiaConvertToDMSex(lon, lat, 0)
*/
GAIAAUX_DECLARE char *gaiaConvertToDMS (double longitude, double latitude);
/**
Return a percent-encoded URL
\param url the URL to be percent-encoded
\param out_charset the charset encoding adopted by the encoded URL
\return the corresponding percent-encoded URL text string,
or NULL on failure
\sa gaiaDecodeURL
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaEncodeURL (const char *url,
const char *in_charset);
/**
Return a clean URL from its percent-encoded representation
\param encoded the percent-encoded URL to be decoded
\param in_charset the charset encoding adopted by the URL to be decoded
\return the corresponding clean URL text string,
or NULL on failure
\sa gaiaEncodeURL
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaDecodeURL (const char *encoded,
const char *out_charset);
/**
Return the DirName component (if any) from a Path
\param path full or relative pathname
\return the corresponding DirName text string,
or NULL on failure
\sa gaiaFullFileNameFromPath, gaiaFileNameFromPath, gaiaFileExtFromPath
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaDirNameFromPath (const char *path);
/**
Return the FullFileName from a Path
\param path full or relative pathname
\return the corresponding FullFileName (including an eventual extension),
or NULL on failure
\sa gaiaDirNameFromPath, gaiaFileNameFromPath, gaiaFileExtFromPath
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaFullFileNameFromPath (const char *path);
/**
Return the FileName from a Path
\param path full or relative pathname
\return the corresponding FileName (excluding an eventual extension),
or NULL on failure
\sa gaiaDirNameFromPath, gaiaFullFileNameFromPath, gaiaFileExtFromPath
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaFileNameFromPath (const char *path);
/**
Return the FileExtension from a Path
\param path full or relative pathname
\return the corresponding FileExtension (if any), or NULL on failure
\sa gaiaDirNameFromPath, gaiaFullFileNameFromPath, gaiaFileNameFromPath
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaFileExtFromPath (const char *path);
/**
Return a text string containing no repeated whitespaces
\param string the input string to be cleaned
\return the corresponding string containing no repeated whitespaces,
or NULL on failure
\note this function will return a dynamically allocated buffer created
by malloc().
You are required to explicitly free() any string returned by this function.
*/
GAIAAUX_DECLARE char *gaiaRemoveExtraSpaces (const char *string);
#ifdef __cplusplus
}
#endif
#endif /* _GAIAAUX_H */
libspatialite-5.1.0/src/headers/spatialite/gaiamatrix.h 0000644 0001750 0001750 00000022617 14463127014 020136 0000000 0000000 /*
gaiamatrix.h -- Gaia common utility functions: affine trasform Matrix
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaiamatrix.h
Auxiliary/helper functions
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef DLL_EXPORT
#define GAIAMATRIX_DECLARE __declspec(dllexport)
#else
#define GAIAMATRIX_DECLARE extern
#endif
#endif
#ifndef _GAIAMATRIX_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIAMATRIX_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
Typedef for gaiaAffineTransformMatrix object (opaque, hidden)
\sa gaiaAffineTransformMatrixPtr
*/
typedef struct priv_affine_transform gaiaAffineTransformMatrix;
/**
Typedef for gaiaAffineTransformMatrixPtr object pointer (opaque, hidden)
\sa gaiaAffineTransformMatrix
*/
typedef gaiaAffineTransformMatrix *gaiaAffineTransformMatrixPtr;
/* function prototypes */
/**
Creating a fully initialized BLOB-Matrix
\param a XX component of the affine transformation.
\param b XY component of the affine transformation.
\param c XZ component of the affine transformation.
\param d YX component of the affine transformation.
\param e YY component of the affine transformation.
\param f YZ component of the affine transformation.
\param g ZX component of the affine transformation.
\param h ZY component of the affine transformation.
\param i ZZ component of the affine transformation.
\param xoff X translation component of the affine transformation.
\param yoff Y translation component of the affine transformation.
\param zoff Z translation component of the affine transformation.
\param blob on completion this variable will contain a BLOB-encoded
affine transform Matrix
\param blob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
\sa gaia_matrix_is_valid, gaia_matrix_as_text,
gaia_matrix_multiply, gaia_matrix_create_multiply,
gaia_matrix_transform_geometry
\note you are responsible to destroy (before or after) any BLOB
returned by this function.
*/
GAIAMATRIX_DECLARE int gaia_matrix_create (double a, double b, double c,
double d, double e, double f,
double g, double h, double i,
double xoff, double yoff,
double zoff,
unsigned char **blob,
int *blob_sz);
/**
Creating a BLOB-Matrix by multiplying MatrixA by MatrixB
\param iblob1 pointer to a BLOB-encoded Matrix A
\param iblob1_sz A BLOB's size (in bytes)
\param iblob2 pointer to a BLOB-encoded Matrix A
\param iblob2_sz A BLOB's size (in bytes)
\param blob on completion this variable will contain a BLOB-encoded
affine transform Matrix
\param blob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
\sa gaia_matrix_create, gaia_matrix_is_valid, gaia_matrix_as_text,
gaia_matrix_create_multiply, gaia_matrix_transform_geometry,
gaia_matrix_invert
\note you are responsible to destroy (before or after) any BLOB
returned by this function.
*/
GAIAMATRIX_DECLARE int gaia_matrix_multiply (const unsigned char *iblob1,
int iblob1_sz,
const unsigned char *iblob2,
int iblob2_sz,
unsigned char **blob,
int *blob_sz);
/**
Creating a BLOB-Matrix by applying a further trasformation to a previous BLOB-Matrix
\param iblob pointer to a BLOB-encoded Matrix
\param iblob_sz BLOB's size (in bytes)
\param a XX component of the affine transformation.
\param b XY component of the affine transformation.
\param c XZ component of the affine transformation.
\param d YX component of the affine transformation.
\param e YY component of the affine transformation.
\param f YZ component of the affine transformation.
\param g ZX component of the affine transformation.
\param h ZY component of the affine transformation.
\param i ZZ component of the affine transformation.
\param xoff X translation component of the affine transformation.
\param yoff Y translation component of the affine transformation.
\param zoff Z translation component of the affine transformation.
\param blob on completion this variable will contain a BLOB-encoded
affine transform Matrix
\param blob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
\sa gaia_matrix_create, gaia_matrix_is_valid, gaia_matrix_as_text,
gaia_matrix_multiply, gaia_matrix_transform_geometry
\note you are responsible to destroy (before or after) any BLOB
returned by this function.
*/
GAIAMATRIX_DECLARE int gaia_matrix_create_multiply (const unsigned char
*iblob, int iblob_sz,
double a, double b,
double c, double d,
double e, double f,
double g, double h,
double i, double xoff,
double yoff,
double zoff,
unsigned char **blob,
int *blob_sz);
/**
Testing a BLOB-Matrix for validity
\param blob pointer to a BLOB-encoded Matrix
\param blob_sz BLOB's size (in bytes)
\return TRUE if the BLOB really is of the BLOB-Matrix type; FALSE if not.
\sa gaia_matrix_create, gaia_matrix_as_text,
gaia_matrix_multiply, gaia_matrix_create_multiply,
gaia_matrix_transform_geometry
*/
GAIAMATRIX_DECLARE int gaia_matrix_is_valid (const unsigned char *blob,
int blob_sz);
/**
Printing a textual represention from a BLOB-Matrix
\param blob pointer to a BLOB-encoded Matrix
\param blob_sz BLOB's size (in bytes)
\return a text string; NULL on failure.
\sa gaia_matrix_create, gaia_matrix_is_valid,
gaia_matrix_multiply, gaia_matrix_create_multiply,
gaia_matrix_transform_geometry
\note you are responsible to destroy (before or after) any text
string returned by this function by calling sqlite3_free().
*/
GAIAMATRIX_DECLARE char *gaia_matrix_as_text (const unsigned char *blob,
int blob_sz);
/**
Transforming a Geometry accordingly to an Affine Transform Matrix
\param geom the input Geometry
\param blob pointer to a BLOB-encoded Matrix
\param blob_sz BLOB's size (in bytes)
\return pointer to the transformed Geometry or NULL on failure.
\sa gaia_matrix_create, gaia_matrix_is_valid, gaia_matrix_as_text,
gaia_matrix_multiply, gaia_matrix_create_multiply
\note you are responsible to destroy (before or after) any Geometry
returned by this function.
*/
GAIAMATRIX_DECLARE gaiaGeomCollPtr
gaia_matrix_transform_geometry (gaiaGeomCollPtr geom,
const unsigned char *blob, int blob_sz);
/**
Computing the Determinant from an Affine Transform Matrix
\param blob pointer to a BLOB-encoded Matrix
\param blob_sz BLOB's size (in bytes)
\return the Determinant of the Matix; 0.0 on invalid args.
\sa gaia_matrix_create, gaia_matrix_is_valid, gaia_matrix_invert
\note you are responsible to destroy (before or after) any Geometry
returned by this function.
*/
GAIAMATRIX_DECLARE double
gaia_matrix_determinant (const unsigned char *blob, int blob_sz);
/**
Creating a BLOB-Matrix by applying a further trasformation to a previous BLOB-Matrix
\param iblob pointer to a BLOB-encoded Matrix
\param iblob_sz BLOB's size (in bytes)
\param blob on completion this variable will contain a BLOB-encoded
affine transform Matrix (Inverse)
\param blob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
Note that not all Matrices can be Inverted, only those having
a valid Determinant.
\sa gaia_matrix_create, gaia_matrix_is_valid, gaia_matrix_multiply,
gaia_matrix_determinant
\note you are responsible to destroy (before or after) any BLOB
returned by this function.
*/
GAIAMATRIX_DECLARE int gaia_matrix_invert (const unsigned char
*iblob, int iblob_sz,
unsigned char **blob,
int *blob_sz);
#ifdef __cplusplus
}
#endif
#endif /* _GAIAMATRIX_H */
libspatialite-5.1.0/src/headers/spatialite/gaiageo.h 0000644 0001750 0001750 00000004462 14463127014 017402 0000000 0000000 /*
gaiageo.h -- Gaia common support for geometries
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Klaus Foerster klaus.foerster@svg.cc
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaiageo.h
Geometry handling functions and constants
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* stdio.h included for FILE objects. */
#include
#ifdef DLL_EXPORT
#define GAIAGEO_DECLARE __declspec(dllexport)
#else
#define GAIAGEO_DECLARE extern
#endif
#endif
#ifndef _GAIAGEO_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIAGEO_H
#endif
#include "gg_const.h"
#include "gg_structs.h"
#include "gg_core.h"
#include "gg_mbr.h"
#include "gg_formats.h"
#include "gg_dynamic.h"
#include "gg_advanced.h"
#include "gg_xml.h"
#endif /* _GAIAGEO_H */
libspatialite-5.1.0/src/headers/spatialite/gg_const.h 0000644 0001750 0001750 00000044666 14463127014 017623 0000000 0000000 /*
gg_const.h -- Gaia common support for geometries: constants
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Klaus Foerster klaus.foerster@svg.cc
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_const.h
Geometry constants and macros
*/
#ifndef _GG_CONST_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_CONST_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constant values for getVectorLayersList modes */
/** mode: FAST (QGIS data-provider) */
#define GAIA_VECTORS_LIST_FAST 0
/** mode: OPTIMISTIC */
#define GAIA_VECTORS_LIST_OPTIMISTIC 1
/** mode: PESSIMISTIC */
#define GAIA_VECTORS_LIST_PESSIMISTIC 2
/* constant values for Vector Layer Types */
/** Vector Layer: unknown type */
#define GAIA_VECTOR_UNKNOWN -1
/** Vector Layer: Spatial Table */
#define GAIA_VECTOR_TABLE 1
/** Vector Layer: Spatial View */
#define GAIA_VECTOR_VIEW 2
/** Vector Layer: Virtual Shape */
#define GAIA_VECTOR_VIRTUAL 3
/* constant values for Vector Layer Geometry Types */
/** Vector Layer Geometry: Geometry */
#define GAIA_VECTOR_GEOMETRY 0
/** Vector Layer Geometry: Point */
#define GAIA_VECTOR_POINT 1
/** Vector Layer Geometry: Linestring */
#define GAIA_VECTOR_LINESTRING 2
/** Vector Layer Geometry: Polygon */
#define GAIA_VECTOR_POLYGON 3
/** Vector Layer Geometry: MultiPoint */
#define GAIA_VECTOR_MULTIPOINT 4
/** Vector Layer Geometry: MultiLinestring */
#define GAIA_VECTOR_MULTILINESTRING 5
/** Vector Layer Geometry: MultiPolygon */
#define GAIA_VECTOR_MULTIPOLYGON 6
/** Vector Layer Geometry: GeometryCollection */
#define GAIA_VECTOR_GEOMETRYCOLLECTION 7
/* constant values for Spatial Index */
/** Vector Layer: no Spatial Index */
#define GAIA_SPATIAL_INDEX_NONE 0
/** Vector Layer: Spatial Index RTree */
#define GAIA_SPATIAL_INDEX_RTREE 1
/** Vector Layer: Spatial Index MbrCache */
#define GAIA_SPATIAL_INDEX_MBRCACHE 2
/* constant values for generic geometry classes */
/** WKT parser: unknown Geometry type */
#define GAIA_TYPE_NONE 0
/** WKT parser: Point Geometry type */
#define GAIA_TYPE_POINT 1
/** WKT parser: Linestring Geometry type */
#define GAIA_TYPE_LINESTRING 2
/** WKT parser: Polygon Geometry type */
#define GAIA_TYPE_POLYGON 3
/* constants that defines byte storage order */
/** Big-Endian marker */
#define GAIA_BIG_ENDIAN 0
/** Little-Endian marker */
#define GAIA_LITTLE_ENDIAN 1
/** TinyPoint Big-Endian marker */
#define GAIA_TINYPOINT_BIG_ENDIAN 0x80
/** TinyPoint Little-Endian marker */
#define GAIA_TINYPOINT_LITTLE_ENDIAN 0x81
/* constants that defines special markers used for encoding of SpatiaLite internal BLOB geometries */
/** BLOB-Geometry internal marker: START */
#define GAIA_MARK_START 0x00
/** BLOB-Geometry internal marker: END */
#define GAIA_MARK_END 0xFE
/** BLOB-Geometry internal marker: MBR */
#define GAIA_MARK_MBR 0x7C
/** BLOB-Geometry internal marker: ENTITY */
#define GAIA_MARK_ENTITY 0x69
/* constants that defines GEOMETRY CLASSes */
/** BLOB-Geometry CLASS: unknown */
#define GAIA_UNKNOWN 0
/** BLOB-Geometry CLASS: POINT */
#define GAIA_POINT 1
/** BLOB-Geometry CLASS: LINESTRING */
#define GAIA_LINESTRING 2
/** BLOB-Geometry CLASS: POLYGON */
#define GAIA_POLYGON 3
/** BLOB-Geometry CLASS: MULTIPOINT */
#define GAIA_MULTIPOINT 4
/** BLOB-Geometry CLASS: MULTILINESTRING */
#define GAIA_MULTILINESTRING 5
/** BLOB-Geometry CLASS: MULTIPOLYGON */
#define GAIA_MULTIPOLYGON 6
/** BLOB-Geometry CLASS: GEOMETRYCOLLECTION */
#define GAIA_GEOMETRYCOLLECTION 7
/** BLOB-Geometry CLASS: POINT Z */
#define GAIA_POINTZ 1001
/** BLOB-Geometry CLASS: LINESTRING Z */
#define GAIA_LINESTRINGZ 1002
/** BLOB-Geometry CLASS: POLYGON Z */
#define GAIA_POLYGONZ 1003
/** BLOB-Geometry CLASS: MULTIPOINT Z */
#define GAIA_MULTIPOINTZ 1004
/** BLOB-Geometry CLASS: MULTILINESTRING Z */
#define GAIA_MULTILINESTRINGZ 1005
/** BLOB-Geometry CLASS: MULTIPOLYGON Z */
#define GAIA_MULTIPOLYGONZ 1006
/** BLOB-Geometry CLASS: GEOMETRYCOLLECTION Z */
#define GAIA_GEOMETRYCOLLECTIONZ 1007
/** BLOB-Geometry CLASS: POINT M */
#define GAIA_POINTM 2001
/** BLOB-Geometry CLASS: LINESTRING M */
#define GAIA_LINESTRINGM 2002
/** BLOB-Geometry CLASS: POLYGON M */
#define GAIA_POLYGONM 2003
/** BLOB-Geometry CLASS: MULTIPOINT M */
#define GAIA_MULTIPOINTM 2004
/** BLOB-Geometry CLASS: MULTILINESTRING M */
#define GAIA_MULTILINESTRINGM 2005
/** BLOB-Geometry CLASS: MULTIPOLYGON M */
#define GAIA_MULTIPOLYGONM 2006
/** BLOB-Geometry CLASS: GEOMETRYCOLLECTION M */
#define GAIA_GEOMETRYCOLLECTIONM 2007
/** BLOB-Geometry CLASS: POINT ZM */
#define GAIA_POINTZM 3001
/** BLOB-Geometry CLASS: LINESTRING ZM */
#define GAIA_LINESTRINGZM 3002
/** BLOB-Geometry CLASS: POLYGON ZM */
#define GAIA_POLYGONZM 3003
/** BLOB-Geometry CLASS: MULTIPOINT ZM */
#define GAIA_MULTIPOINTZM 3004
/** BLOB-Geometry CLASS: MULTILINESTRING ZM */
#define GAIA_MULTILINESTRINGZM 3005
/** BLOB-Geometry CLASS: MULTIPOLYGON ZM */
#define GAIA_MULTIPOLYGONZM 3006
/** BLOB-Geometry CLASS: GEOMETRYCOLLECTION ZM */
#define GAIA_GEOMETRYCOLLECTIONZM 3007
/* constants that defines TinyPoint Types */
/** BLOB-TinyPoint Type: POINT XY */
#define GAIA_TINYPOINT_XY 0x01
/** BLOB-TinyPoint Type: POINT XYZ */
#define GAIA_TINYPOINT_XYZ 0x02
/** BLOB-TinyPoint Type: POINT XYM */
#define GAIA_TINYPOINT_XYM 0x03
/** BLOB-TinyPoint Type: POINT XYZM */
#define GAIA_TINYPOINT_XYZM 0x04
/* constants that defines Compressed GEOMETRY CLASSes */
/** BLOB-Geometry CLASS: compressed LINESTRING */
#define GAIA_COMPRESSED_LINESTRING 1000002
/** BLOB-Geometry CLASS: compressed POLYGON */
#define GAIA_COMPRESSED_POLYGON 1000003
/** BLOB-Geometry CLASS: compressed LINESTRING Z */
#define GAIA_COMPRESSED_LINESTRINGZ 1001002
/** BLOB-Geometry CLASS: compressed POLYGON Z */
#define GAIA_COMPRESSED_POLYGONZ 1001003
/** BLOB-Geometry CLASS: compressed LINESTRING M */
#define GAIA_COMPRESSED_LINESTRINGM 1002002
/** BLOB-Geometry CLASS: compressed POLYGON M */
#define GAIA_COMPRESSED_POLYGONM 1002003
/** BLOB-Geometry CLASS: compressed LINESTRING ZM */
#define GAIA_COMPRESSED_LINESTRINGZM 1003002
/** BLOB-Geometry CLASS: compressed POLYGON ZM */
#define GAIA_COMPRESSED_POLYGONZM 1003003
/* constants that defines GEOS-WKB 3D CLASSes */
/** GEOS-WKB 3D CLASS: POINT Z */
#define GAIA_GEOSWKB_POINTZ -2147483647
/** GEOS-WKB 3D CLASS: LINESTRING Z */
#define GAIA_GEOSWKB_LINESTRINGZ -2147483646
/** GEOS-WKB 3D CLASS: POLYGON Z */
#define GAIA_GEOSWKB_POLYGONZ -2147483645
/** GEOS-WKB 3D CLASS: MULTIPOINT Z */
#define GAIA_GEOSWKB_MULTIPOINTZ -2147483644
/** GEOS-WKB 3D CLASS: MULTILINESTRING Z */
#define GAIA_GEOSWKB_MULTILINESTRINGZ -2147483643
/** GEOS-WKB 3D CLASS: MULTIPOLYGON Z */
#define GAIA_GEOSWKB_MULTIPOLYGONZ -2147483642
/** GEOS-WKB 3D CLASS: POINT Z */
#define GAIA_GEOSWKB_GEOMETRYCOLLECTIONZ -2147483641
/* constants that defines multitype values */
/** DBF data type: NULL */
#define GAIA_NULL_VALUE 0
/** DBF data type: TEXT */
#define GAIA_TEXT_VALUE 1
/** DBF data type: INT */
#define GAIA_INT_VALUE 2
/** DBF data type: DOUBLE */
#define GAIA_DOUBLE_VALUE 3
/* constants that defines POINT index for LINESTRING */
/** Linestring/Ring functions: START POINT */
#define GAIA_START_POINT 1
/** Linestring/Ring functions: END POINT */
#define GAIA_END_POINT 2
/** Linestring/Ring functions: POINTN */
#define GAIA_POINTN 3
/* constants that defines MBRs spatial relationships */
/** MBR relationships: CONTAINS */
#define GAIA_MBR_CONTAINS 1
/** MBR relationships: DISJOINT */
#define GAIA_MBR_DISJOINT 2
/** MBR relationships: EQUAL */
#define GAIA_MBR_EQUAL 3
/** MBR relationships: INTERSECTS */
#define GAIA_MBR_INTERSECTS 4
/** MBR relationships: OVERLAP */
#define GAIA_MBR_OVERLAPS 5
/** MBR relationships: TOUCHES */
#define GAIA_MBR_TOUCHES 6
/** MBR relationships: WITHIN */
#define GAIA_MBR_WITHIN 7
/* constants used for FilterMBR */
/** FilerMBR relationships: WITHIN */
#define GAIA_FILTER_MBR_WITHIN 74
/** FilerMBR relationships: CONTAINS */
#define GAIA_FILTER_MBR_CONTAINS 77
/** FilerMBR relationships: INTERSECTS */
#define GAIA_FILTER_MBR_INTERSECTS 79
/** FilerMBR relationships: DECLARE */
#define GAIA_FILTER_MBR_DECLARE 89
/* constants defining SVG default values */
/** SVG precision: RELATIVE */
#define GAIA_SVG_DEFAULT_RELATIVE 0
/** SVG precision: DEFAULT */
#define GAIA_SVG_DEFAULT_PRECISION 6
/** SVG precision: MAX */
#define GAIA_SVG_DEFAULT_MAX_PRECISION 15
/* constants used for VirtualNetwork */
/** VirtualNetwork internal markers: START */
#define GAIA_NET_START 0x67
/** VirtualNetwork internal markers: 64 bit START */
#define GAIA_NET64_START 0x68
/** VirtualNetwork internal markers: A-Stat START */
#define GAIA_NET64_A_STAR_START 0x69
/** VirtualNetwork internal markers: END */
#define GAIA_NET_END 0x87
/** VirtualNetwork internal markers: HEADER */
#define GAIA_NET_HEADER 0xc0
/** VirtualNetwork internal markers: CODE */
#define GAIA_NET_CODE 0xa6
/** VirtualNetwork internal markers: ID */
#define GAIA_NET_ID 0xb5
/** VirtualNetwork internal markers: NODE */
#define GAIA_NET_NODE 0xde
/** VirtualNetwork internal markers: ARC */
#define GAIA_NET_ARC 0x54
/** VirtualNetwork internal markers: TABLE */
#define GAIA_NET_TABLE 0xa0
/** VirtualNetwork internal markers: FROM */
#define GAIA_NET_FROM 0xa1
/** VirtualNetwork internal markers: TO */
#define GAIA_NET_TO 0xa2
/** VirtualNetwork internal markers: GEOM */
#define GAIA_NET_GEOM 0xa3
/** VirtualNetwork internal markers: NAME */
#define GAIA_NET_NAME 0xa4
/** VirtualNetwork internal markers: COEFF */
#define GAIA_NET_A_STAR_COEFF 0xa5
/** VirtualNetwork internal markers: BLOCK */
#define GAIA_NET_BLOCK 0xed
/* constants used for Coordinate Dimensions */
/** Coordinate Dimensions: XY */
#define GAIA_XY 0x00
/** Coordinate Dimensions: XYZ */
#define GAIA_XY_Z 0x01
/** Coordinate Dimensions: XYM */
#define GAIA_XY_M 0x02
/** Coordinate Dimensions: XYZM */
#define GAIA_XY_Z_M 0x03
/* constants used for length unit conversion */
/** Length unit conversion: Kilometer */
#define GAIA_KM 0
/** Length unit conversion: Meter */
#define GAIA_M 1
/** Length unit conversion: Decimeter */
#define GAIA_DM 2
/** Length unit conversion: Centimeter */
#define GAIA_CM 3
/** Length unit conversion: Millimeter */
#define GAIA_MM 4
/** Length unit conversion: International Nautical Mile */
#define GAIA_KMI 5
/** Length unit conversion: Inch */
#define GAIA_IN 6
/** Length unit conversion: Feet */
#define GAIA_FT 7
/** Length unit conversion: Yard */
#define GAIA_YD 8
/** Length unit conversion: Mile */
#define GAIA_MI 9
/** Length unit conversion: Fathom */
#define GAIA_FATH 10
/** Length unit conversion: Chain */
#define GAIA_CH 11
/** Length unit conversion: Link */
#define GAIA_LINK 12
/** Length unit conversion: US Inch */
#define GAIA_US_IN 13
/** Length unit conversion: US Feet */
#define GAIA_US_FT 14
/** Length unit conversion: US Yard */
#define GAIA_US_YD 15
/** Length unit conversion: US Chain */
#define GAIA_US_CH 16
/** Length unit conversion: US Mile */
#define GAIA_US_MI 17
/** Length unit conversion: Indian Yard */
#define GAIA_IND_YD 18
/** Length unit conversion: Indian Feet */
#define GAIA_IND_FT 19
/** Length unit conversion: Indian Chain */
#define GAIA_IND_CH 20
/** Length unit conversion: MIN */
#define GAIA_MIN_UNIT GAIA_KM
/** Length unit conversion: MAX */
#define GAIA_MAX_UNIT GAIA_IND_CH
/* constants used for SHAPES */
/** SHP shape: unknown */
#define GAIA_SHP_NULL 0
/** SHP shape: POINT */
#define GAIA_SHP_POINT 1
/** SHP shape: POLYLINE */
#define GAIA_SHP_POLYLINE 3
/** SHP shape: POLYGON */
#define GAIA_SHP_POLYGON 5
/** SHP shape: MULTIPOINT */
#define GAIA_SHP_MULTIPOINT 8
/** SHP shape: POINT Z */
#define GAIA_SHP_POINTZ 11
/** SHP shape: POLYLINE Z */
#define GAIA_SHP_POLYLINEZ 13
/** SHP shape: POLYGON Z */
#define GAIA_SHP_POLYGONZ 15
/** SHP shape: MULTIPOINT Z */
#define GAIA_SHP_MULTIPOINTZ 18
/** SHP shape: POINT M */
#define GAIA_SHP_POINTM 21
/** SHP shape: POLYLINE M */
#define GAIA_SHP_POLYLINEM 23
/** SHP shape: POLYGON M */
#define GAIA_SHP_POLYGONM 25
/** SHP shape: MULTIPOINT M */
#define GAIA_SHP_MULTIPOINTM 28
/* constants used for Clone Special modes */
/** Clone Special Mode: Same Order as input */
#define GAIA_SAME_ORDER 0
/** Clone Special Mode: Reversed Order */
#define GAIA_REVERSE_ORDER -1
/** Clone Special Mode: apply Clockwise Rule to Polygon Rings */
#define GAIA_CW_ORDER -2
/** Clone Special Mode: apply Counter-Clockwise Rule to Polygon Rings */
#define GAIA_CCW_ORDER -3
/* constants used for DBF column-names case */
/** Leave all DBF column-names as they are */
#define GAIA_DBF_COLNAME_CASE_IGNORE 0
/** Convert all DBF column names to LowerCase */
#define GAIA_DBF_COLNAME_LOWERCASE 1
/** Convert all DBF column names to UpperCase */
#define GAIA_DBF_COLNAME_UPPERCASE 2
/* constants used for PROJ.6 WKT styles */
/** WKT style is ISO-2018 */
#define GAIA_PROJ_WKT_ISO_2018 1
/** WKT style is ISO-2015 */
#define GAIA_PROJ_WKT_ISO_2015 2
/** WKT style is GDAL */
#define GAIA_PROJ_WKT_GDAL 3
/** WKT style is ESRI */
#define GAIA_PROJ_WKT_ESRI 4
/* macros */
/**
macro extracting XY coordinates
\param xy pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double *] X coordinate
\param y [double *] Y coordinate
\sa gaiaLineGetPoint, gaiaRingGetPoint
\note using this macro on behalf of COORDs not of [XY] dims may cause serious
problems
*/
#define gaiaGetPoint(xy,v,x,y) \
{*x = xy[(v) * 2]; \
*y = xy[(v) * 2 + 1];}
/**
macro setting XY coordinates
\param xy pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double] X coordinate
\param y [double] Y coordinate
\sa gaiaLineSetPoint, gaiaRingSetPoint
\note using this macro on behalf on COORDs not of [XY] dims may cause
serious problems
*/
#define gaiaSetPoint(xy,v,x,y) \
{xy[(v) * 2] = x; \
xy[(v) * 2 + 1] = y;}
/**
macro extracting XYZ coordinates
\param xyz pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double *] X coordinate
\param y [double *] Y coordinate
\param z [double *] Z coordinate
\sa gaiaLineGetPoint, gaiaRingGetPoint
\note using this macro on behalf of COORDs not of [XYZ] dims may cause serious
problems
*/
#define gaiaGetPointXYZ(xyz,v,x,y,z) \
{*x = xyz[(v) * 3]; \
*y = xyz[(v) * 3 + 1]; \
*z = xyz[(v) * 3 + 2];}
/**
macro setting XYZ coordinates
\param xyz pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double] X coordinate
\param y [double] Y coordinate
\param z [double] Z coordinate
\sa gaiaLineSetPoint, gaiaRingSetPoint
\note using this macro on behalf on COORDs not of [XYZ] dims may cause
serious problems
*/
#define gaiaSetPointXYZ(xyz,v,x,y,z) \
{xyz[(v) * 3] = x; \
xyz[(v) * 3 + 1] = y; \
xyz[(v) * 3 + 2] = z;}
/**
macro extracting XYM coordinates
\param xym pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double *] X coordinate
\param y [double *] Y coordinate
\param m [double *] M measure
\sa gaiaLineGetPoint, gaiaRingGetPoint
\note using this macro on behalf of COORDs not of [XYM] dims may cause serious
problems
*/
#define gaiaGetPointXYM(xym,v,x,y,m) \
{*x = xym[(v) * 3]; \
*y = xym[(v) * 3 + 1]; \
*m = xym[(v) * 3 + 2];}
/**
macro setting XYM coordinates
\param xym pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double] X coordinate
\param y [double] Y coordinate
\param m [double] M measure
\sa gaiaLineSetPoint, gaiaRingSetPoint
\note using this macro on behalf on COORDs not of [XYM] dims may cause
serious problems
*/
#define gaiaSetPointXYM(xym,v,x,y,m) \
{xym[(v) * 3] = x; \
xym[(v) * 3 + 1] = y; \
xym[(v) * 3 + 2] = m;}
/**
macro extracting XYZM coordinates
\param xyzm pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double *] X coordinate
\param y [double *] Y coordinate
\param z [double *] Z coordinate
\param m [double *] M measure
\sa gaiaLineGetPoint, gaiaRingGetPoint
\note using this macro on behalf of COORDs not of [XYZM] dims may cause serious
problems
*/
#define gaiaGetPointXYZM(xyzm,v,x,y,z,m) \
{*x = xyzm[(v) * 4]; \
*y = xyzm[(v) * 4 + 1]; \
*z = xyzm[(v) * 4 + 2]; \
*m = xyzm[(v) * 4 + 3];}
/**
macro setting XYZM coordinates
\param xyzm pointer [const void *] to COORD mem-array
\param v [int] point index [first point has index 0]
\param x [double] X coordinate
\param y [double] Y coordinate
\param z [double] Z coordinate
\param m [double] M measure
\sa gaiaLineSetPoint, gaiaRingSetPoint
\note using this macro on behalf on COORDs not of [XYZM] dims may cause
serious problems
*/
#define gaiaSetPointXYZM(xyzm,v,x,y,z,m) \
{xyzm[(v) * 4] = x; \
xyzm[(v) * 4 + 1] = y; \
xyzm[(v) * 4 + 2] = z; \
xyzm[(v) * 4 + 3] = m;}
#ifdef __cplusplus
}
#endif
#endif /* _GG_CONST_H */
libspatialite-5.1.0/src/headers/spatialite/gg_structs.h 0000644 0001750 0001750 00000060260 14463127014 020170 0000000 0000000 /*
gg_structs.h -- Gaia common support for geometries: structures
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_structs.h
Geometry structures
*/
#ifndef _GG_STRUCTS_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_STRUCTS_H
#endif
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif
/* supporting files bigger than 2 GB */
#ifdef _WIN32 /* windows */
#define gaia_off_t __int64
#define gaia_fseek _fseeki64
#else /* not windows */
#define gaia_off_t off_t
#define gaia_fseek fseeko
#endif
/**
Container for OGC POINT Geometry
*/
typedef struct gaiaPointStruct
{
/* an OpenGis POINT */
/** X coordinate */
double X; /* X,Y coordinates */
/** Y coordinate */
double Y;
/** Z coordinate: only for XYZ and XYZM dims */
double Z; /* Z coordinate */
/** M measure: only for XYM and XYZM dims */
double M; /* M measure */
/** one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int DimensionModel; /* (x,y), (x,y,z), (x,y,m) or (x,y,z,m) */
/** pointer to next item [double linked list] */
struct gaiaPointStruct *Next; /* for double-linked list */
/** pointer to previous item [double linked list] */
struct gaiaPointStruct *Prev; /* for double-linked list */
} gaiaPoint;
/**
Typedef for OGC POINT structure
\sa gaiaPoint
*/
typedef gaiaPoint *gaiaPointPtr;
/**
Container for dynamically growing line/ring
*/
typedef struct gaiaDynamicLineStruct
{
/* a generic DYNAMIC LINE object */
/** invalid object */
int Error;
/** the SRID */
int Srid;
/** pointer to first POINT [double linked list] */
gaiaPointPtr First; /* Points linked list - first */
/** pointer to last POINT [double linked list] */
gaiaPointPtr Last; /* Points linked list - last */
} gaiaDynamicLine;
/**
Typedef for dynamically growing line/ring structure
\sa gaiaDynamicLine
*/
typedef gaiaDynamicLine *gaiaDynamicLinePtr;
/**
Container for OGC LINESTRING Geometry
*/
typedef struct gaiaLinestringStruct
{
/* an OpenGis LINESTRING */
/** number of points [aka vertices] */
int Points; /* number of vertices */
/** COORDs mem-array */
double *Coords; /* X,Y [vertices] array */
/** MBR: min X */
double MinX; /* MBR - BBOX */
/** MBR: min Y */
double MinY; /* MBR - BBOX */
/** MBR: max X */
double MaxX; /* MBR - BBOX */
/** MBR: max X */
double MaxY; /* MBR - BBOX */
/** one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int DimensionModel; /* (x,y), (x,y,z), (x,y,m) or (x,y,z,m) */
/** pointer to next item [linked list] */
struct gaiaLinestringStruct *Next; /* for linked list */
} gaiaLinestring;
/**
Typedef for OGC LINESTRING structure
\sa gaiaLinestring
*/
typedef gaiaLinestring *gaiaLinestringPtr;
/**
Container for OGC RING Geometry
*/
typedef struct gaiaRingStruct
{
/* a GIS ring - OpenGis LINESTRING, closed */
/** number of points [aka vertices] */
int Points; /* number of vertices */
/** COORDs mem-array */
double *Coords; /* X,Y [vertices] array */
/** clockwise / counterclockwise */
int Clockwise; /* clockwise / counterclockwise */
/** MBR: min X */
double MinX; /* MBR - BBOX */
/** MBR: min Y */
double MinY; /* MBR - BBOX */
/** MBR: max X */
double MaxX; /* MBR - BBOX */
/** MBR: max Y */
double MaxY; /* MBR - BBOX */
/** one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int DimensionModel; /* (x,y), (x,y,z), (x,y,m) or (x,y,z,m) */
/** pointer to next item [linked list] */
struct gaiaRingStruct *Next; /* for linked list */
/** pointer to belonging Polygon */
struct gaiaPolygonStruct *Link; /* polygon reference */
} gaiaRing;
/**
Typedef for OGC RING structure
\sa gaiaRing
*/
typedef gaiaRing *gaiaRingPtr;
/**
Container for OGC POLYGON Geometry
*/
typedef struct gaiaPolygonStruct
{
/* an OpenGis POLYGON */
/** the exterior ring (mandatory) */
gaiaRingPtr Exterior; /* exterior ring */
/** number of interior rings (may be, none) */
int NumInteriors; /* number of interior rings */
/** array of interior rings */
gaiaRingPtr Interiors; /* interior rings array */
/** index of first unused interior ring */
int NextInterior; /* first free interior ring */
/** MBR: min X */
double MinX; /* MBR - BBOX */
/** MBR: min Y */
double MinY; /* MBR - BBOX */
/** MBR: max X */
double MaxX; /* MBR - BBOX */
/** MBR: max Y */
double MaxY; /* MBR - BBOX */
/** one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int DimensionModel; /* (x,y), (x,y,z), (x,y,m) or (x,y,z,m) */
/** pointer to next item [linked list] */
struct gaiaPolygonStruct *Next; /* for linked list */
} gaiaPolygon;
/**
Typedef for OGC POLYGON structure
\sa gaiaPolygon
*/
typedef gaiaPolygon *gaiaPolygonPtr;
/**
Container for OGC GEOMETRYCOLLECTION Geometry
*/
typedef struct gaiaGeomCollStruct
{
/* OpenGis GEOMETRYCOLLECTION */
/** the SRID */
int Srid; /* the SRID value for this GEOMETRY */
/** CPU endian arch */
char endian_arch; /* littleEndian - bigEndian arch for target CPU */
/** BLOB Geometry endian arch */
char endian; /* littleEndian - bigEndian */
/** BLOB-Geometry buffer */
const unsigned char *blob; /* WKB encoded buffer */
/** BLOB-Geometry buffer size (in bytes) */
unsigned long size; /* buffer size */
/** current offset [BLOB parsing] */
unsigned long offset; /* current offset [for parsing] */
/** pointer to first POINT [linked list]; may be NULL */
gaiaPointPtr FirstPoint; /* Points linked list - first */
/** pointer to last POINT [linked list]; may be NULL */
gaiaPointPtr LastPoint; /* Points linked list - last */
/** pointer to first LINESTRING [linked list]; may be NULL */
gaiaLinestringPtr FirstLinestring; /* Linestrings linked list - first */
/** pointer to last LINESTRING [linked list]; may be NULL */
gaiaLinestringPtr LastLinestring; /* Linestrings linked list - last */
/** pointer to first POLYGON [linked list]; may be NULL */
gaiaPolygonPtr FirstPolygon; /* Polygons linked list - first */
/** pointer to last POLYGON [linked list]; may be NULL */
gaiaPolygonPtr LastPolygon; /* Polygons linked list - last */
/** MBR: min X */
double MinX; /* MBR - BBOX */
/** MBR: min Y */
double MinY; /* MBR - BBOX */
/** MBR: max X */
double MaxX; /* MBR - BBOX */
/** MBR: max Y */
double MaxY; /* MBR - BBOX */
/** one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int DimensionModel; /* (x,y), (x,y,z), (x,y,m) or (x,y,z,m) */
/** any valid Geometry Class type */
int DeclaredType; /* the declared TYPE for this Geometry */
/** pointer to next item [linked list] */
struct gaiaGeomCollStruct *Next; /* Vanuatu - used for linked list */
} gaiaGeomColl;
/**
Typedef for OGC GEOMETRYCOLLECTION structure
\sa gaiaGeomCool
*/
typedef gaiaGeomColl *gaiaGeomCollPtr;
/**
Container similar to LINESTRING [internally used]
*/
typedef struct gaiaPreRingStruct
{
/* a LINESTRING used to build rings */
/** pointer to LINESTRING */
gaiaLinestringPtr Line; /* a LINESTRING pointer */
/** already used/visited item */
int AlreadyUsed; /* a switch to mark an already used line element */
/** pointer to next item [linked list] */
struct gaiaPreRingStruct *Next; /* for linked list */
} gaiaPreRing;
/**
Typedef for gaiaPreRing structure
\sa gaiaPreRing
*/
typedef gaiaPreRing *gaiaPreRingPtr;
/**
Container for variant (multi-type) value
*/
typedef struct gaiaValueStruct
{
/* a DBF field multitype value */
/** data type: one of GAIA_NULL_VALUE, GAIA_INT_VALUE, GAIA_DOUBLE_VALUE, GAIA_TEXT_VALUE */
short Type; /* the type */
/** TEXT type value */
char *TxtValue; /* the text value */
/** INT type value */
sqlite3_int64 IntValue; /* the integer value */
/** DOUBLE type value */
double DblValue; /* the double value */
} gaiaValue;
/**
Typedef for variant (multi-type) value structure
*/
typedef gaiaValue *gaiaValuePtr;
/**
Container for DBF field
*/
typedef struct gaiaDbfFieldStruct
{
/* a DBF field definition - shapefile attribute */
/** field name */
char *Name; /* field name */
/** DBF data type */
unsigned char Type; /* field type */
/** DBF buffer offset [where the field value starts] */
int Offset; /* buffer offset [this field begins at *buffer+offset* and extends for *length* bytes */
/** total DBF buffer field length (in bytes) */
unsigned char Length; /* field total length [in bytes] */
/** precision (decimal digits) */
unsigned char Decimals; /* decimal positions */
/** current variant [multi-type] value */
gaiaValuePtr Value; /* the current multitype value for this attribute */
/** pointer to next item [linked list] */
struct gaiaDbfFieldStruct *Next; /* pointer to next element in linked list */
} gaiaDbfField;
/**
Typedef for DBF field structure
*/
typedef gaiaDbfField *gaiaDbfFieldPtr;
/**
Container for a list of DBF fields
*/
typedef struct gaiaDbfListStruct
{
/* a linked list to contain the DBF fields definitions - shapefile attributes */
/** current RowID */
int RowId; /* the current RowId */
/** current Geometry */
gaiaGeomCollPtr Geometry; /* geometry for current entity */
/** pointer to first DBF field [linked list] */
gaiaDbfFieldPtr First; /* pointer to first element in linked list */
/** pointer to last DBF field [linked list] */
gaiaDbfFieldPtr Last; /* pointer to last element in linker list */
} gaiaDbfList;
/**
Typedef for a list of DBF fields
\sa gaiaDbfList
*/
typedef gaiaDbfList *gaiaDbfListPtr;
/**
A Memory based File
*/
typedef struct gaiaMemFileStruct
{
/* Memory File Type */
char *path;
void *buf;
uint64_t size;
uint64_t offset;
} gaiaMemFile;
/**
Typedef for Memory File structure
\sa gaiaMemFile
*/
typedef gaiaMemFile *gaiaMemFilePtr;
/**
Container for DBF file handling
*/
typedef struct gaiaDbfStruct
{
/* DBF TYPE */
/** DBF endian arch */
int endian_arch;
/** validity flag: 1 = ready to be processed */
int Valid; /* 1 = ready to process */
/** DBF file pathname */
char *Path; /* the DBF path */
/** FILE handle */
FILE *flDbf; /* the DBF file handle */
/** Memory based DBF file */
gaiaMemFilePtr memDbf; /* the DBF memory file */
/** list of DBF fields */
gaiaDbfListPtr Dbf; /* the DBF attributes list */
/** I/O buffer */
unsigned char *BufDbf; /* the DBF I/O buffer */
/** header size (in bytes) */
int DbfHdsz; /* the DBF header length */
/** record length (in bytes) */
int DbfReclen; /* the DBF record length */
/** current file size */
int DbfSize; /* current DBF size */
/** current Record Number */
int DbfRecno; /* current DBF record number */
/** handle to ICONV converter object */
void *IconvObj; /* opaque reference to ICONV converter */
/** last error message (may be NULL) */
char *LastError; /* last error message */
} gaiaDbf;
/**
Typedef for DBF file handler structure
\sa gaiaDbf
*/
typedef gaiaDbf *gaiaDbfPtr;
/**
Container for SHP file handling
*/
typedef struct gaiaShapefileStruct
{
/* SHAPEFILE TYPE */
/** SHP endian arch */
int endian_arch;
/** validity flag: 1 = ready to be processed */
int Valid; /* 1 = ready to process */
/** read or write mode */
int ReadOnly; /* read or write mode */
/** SHP 'abstract' path (no suffixes) */
char *Path; /* the shapefile abstract path [no suffixes] */
/** FILE handle to SHX file */
FILE *flShx; /* the SHX file handle */
/** FILE handle to SHP file */
FILE *flShp; /* the SHP file handle */
/** FILE handle to DBF file */
FILE *flDbf; /* the DBF file handle */
/** Memory based SHX file */
gaiaMemFilePtr memShx; /* the SHX memory file */
/** Memory based SHP file */
gaiaMemFilePtr memShp; /* the SHP memory file */
/** Memory based DBF file */
gaiaMemFilePtr memDbf; /* the DBF memory file */
/** the SHP shape code */
int Shape; /* the SHAPE code for the whole shapefile */
/** list of DBF fields */
gaiaDbfListPtr Dbf; /* the DBF attributes list */
/** DBF I/O buffer */
unsigned char *BufDbf; /* the DBF I/O buffer */
/** DBF header size (in bytes) */
int DbfHdsz; /* the DBF header length */
/** DBF record length (in bytes) */
int DbfReclen; /* the DBF record length */
/** DBF current file size (in bytes) */
int DbfSize; /* current DBF size */
/** DBF current Record Number */
int DbfRecno; /* current DBF record number */
/** SHP I/O buffer */
unsigned char *BufShp; /* the SHP I/O buffer */
/** SHP current buffer size (in bytes) */
int ShpBfsz; /* the SHP buffer current size */
/** SHP current file size */
int ShpSize; /* current SHP size */
/** SHX current file size */
int ShxSize; /* current SHX size */
/** Total Extent: min X */
double MinX; /* the MBR/BBOX for the whole shapefile */
/** Total Extent: min Y */
double MinY;
/** Total Extent: max X */
double MaxX;
/** Total Extent: max Y */
double MaxY;
/** handle to ICONV converter object */
void *IconvObj; /* opaque reference to ICONV converter */
/** last error message (may be NULL) */
char *LastError; /* last error message */
/** SHP actual OGC Geometry type */
int EffectiveType; /* the effective Geometry-type, as determined by gaiaShpAnalyze() */
/** SHP actual dims: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int EffectiveDims; /* the effective Dimensions [XY, XYZ, XYM, XYZM], as determined by gaiaShpAnalyze() */
} gaiaShapefile;
/**
Typedef for SHP file handler structure
\sa gaiaShapefile
*/
typedef gaiaShapefile *gaiaShapefilePtr;
/**
Container for dynamically growing output buffer
*/
typedef struct gaiaOutBufferStruct
{
/* a struct handling a dynamically growing output buffer */
/** current buffer */
char *Buffer;
/** current write offset */
int WriteOffset;
/** current buffer size (in bytes) */
int BufferSize;
/** validity flag */
int Error;
} gaiaOutBuffer;
/**
Typedef for dynamically growing output buffer structure
\sa gaiaOutBuffer
*/
typedef gaiaOutBuffer *gaiaOutBufferPtr;
#ifndef OMIT_ICONV /* ICONV enabled: supporting text reader */
/** Virtual Text driver: MAX number of fields */
#define VRTTXT_FIELDS_MAX 65535
/** Virtual Text driver: MAX block size (in bytes) */
#define VRTTXT_BLOCK_MAX 65535
/** Virtual Text driver: TEXT value */
#define VRTTXT_TEXT 1
/** Virtual Text driver: INTEGER value */
#define VRTTXT_INTEGER 2
/** Virtual Text driver: DOUBLE value */
#define VRTTXT_DOUBLE 3
/** Virtual Text driver: NULL value */
#define VRTTXT_NULL 4
/**
Container for Virtual Text record (line)
*/
struct vrttxt_line
{
/* a struct representing a full LINE (aka Record) */
/** current offset (parsing) */
gaia_off_t offset;
/** line length (in bytes) */
int len;
/** array of field offsets (where each field starts) */
int field_offsets[VRTTXT_FIELDS_MAX];
/** number of field into the record */
int num_fields;
/** validity flag */
int error;
};
/**
Container for Virtual Text record (line) offsets
*/
struct vrttxt_row
{
/* a struct storing Row offsets */
/** Line Number */
int line_no;
/** start offset */
gaia_off_t offset;
/** record (line) length (in bytes) */
int len;
/** number of fields into this record */
int num_fields;
};
/**
Container for Virtual Text block of records
*/
struct vrttxt_row_block
{
/*
/ for efficiency sake, individual Row offsets
/ are grouped in reasonably sized blocks
*/
/** array of records [lines] */
struct vrttxt_row rows[VRTTXT_BLOCK_MAX];
/** number of records into the array */
int num_rows;
/** min Line Number */
int min_line_no;
/** max Line Number */
int max_line_no;
/** pointer to next item [linked list] */
struct vrttxt_row_block *next;
};
/**
Container for Virtual Text column (field) header
*/
struct vrttxt_column_header
{
/* a struct representing a Column (aka Field) header */
/** column name */
char *name;
/** data type: one of GAIA_NULL_VALUE, GAIA_INT_VALUE, GAIA_DOUBLE_VALUE, GAIA_TEXT_VALUE */
int type;
};
/**
Container for Virtual Text file handling
*/
typedef struct vrttxt_reader
{
/* the main TXT-Reader struct */
/** array of columns (fields) */
struct vrttxt_column_header columns[VRTTXT_FIELDS_MAX];
/** FILE handle */
FILE *text_file;
/** handle to ICONV converter object */
void *toUtf8; /* the UTF-8 ICONV converter */
/** field separator character */
char field_separator;
/** text separator character (quote) */
char text_separator;
/** decimal separator */
char decimal_separator;
/** TRUE if the first line contains column names */
int first_line_titles;
/** validity flag */
int error;
/** pointer to first block of records [linked list] */
struct vrttxt_row_block *first;
/** pointer to last block of records [linked list] */
struct vrttxt_row_block *last;
/** array of pointers to individual records [lines] */
struct vrttxt_row **rows;
/** number of records */
int num_rows;
/** current Line Number */
int line_no;
/** max number of columns (fields) */
int max_fields;
/** current buffer size */
int current_buf_sz;
/** current buffer offset [parsing] */
int current_buf_off;
/** I/O buffer */
char *line_buffer;
/** current field buffer */
char *field_buffer;
/** array of field offsets [current record] */
int field_offsets[VRTTXT_FIELDS_MAX];
/** array of field lengths [current record] */
int field_lens[VRTTXT_FIELDS_MAX];
/** max field [current record] */
int max_current_field;
/** current record [line] ready for parsing */
int current_line_ready;
} gaiaTextReader;
/**
Typedef for Virtual Text file handling structure
\sa gaiaTextReader
*/
typedef gaiaTextReader *gaiaTextReaderPtr;
#endif /* end ICONV (text reader) */
/**
Layer Extent infos
*/
typedef struct gaiaLayerExtentInfos
{
/** row count (aka feature count) */
int Count;
/** Extent: min X */
double MinX; /* MBR - BBOX */
/** Extent: min Y */
double MinY; /* MBR - BBOX */
/** Extent: max X */
double MaxX; /* MBR - BBOX */
/** Extent: max Y */
double MaxY; /* MBR - BBOX */
} gaiaLayerExtent;
/**
Typedef for Layer Extent infos
\sa gaiaLayerExtent
*/
typedef gaiaLayerExtent *gaiaLayerExtentPtr;
/**
Layer Auth infos
*/
typedef struct gaiaLayerAuthInfos
{
/** Read-Only layer: TRUE or FALSE */
int IsReadOnly;
/** Hidden layer: TRUE or FALSE */
int IsHidden;
/** Flag indicating if the Capabilities of the SpatialView supports Inserting: TRUE or FALSE */
int HasTriggerInsert;
/** Flag indicating if the Capabilities of the SpatialView supports Updating: TRUE or FALSE */
int HasTriggerUpdate;
/** Flag indicating if the Capabilities of the SpatialView supports Deleting: TRUE or FALSE */
int HasTriggerDelete;
} gaiaLayerAuth;
/**
Typedef for Layer Auth infos
\sa gaiaLayerAuth
*/
typedef gaiaLayerAuth *gaiaLayerAuthPtr;
/**
Attribute/Field MaxSize/Length infos
*/
typedef struct gaiaAttributeFieldMaxSizeInfos
{
/** MaxSize / MaxLength */
int MaxSize;
} gaiaAttributeFieldMaxSize;
/**
Typedef for Attribute/Field MaxSize/Length infos
\sa gaiaAttributeFieldMaxSize
*/
typedef gaiaAttributeFieldMaxSize *gaiaAttributeFieldMaxSizePtr;
/**
Attribute/Field Integer range infos
*/
typedef struct gaiaAttributeFieldIntRangeInfos
{
/** Minimum value */
sqlite3_int64 MinValue;
/** Maximum value */
sqlite3_int64 MaxValue;
} gaiaAttributeFieldIntRange;
/**
Typedef for Attribute/Field Integer range infos
\sa gaiaAttributeFieldIntRange
*/
typedef gaiaAttributeFieldIntRange *gaiaAttributeFieldIntRangePtr;
/**
Attribute/Field Double range infos
*/
typedef struct gaiaAttributeFieldDoubleRangeInfos
{
/** Minimum value */
double MinValue;
/** Maximum value */
double MaxValue;
} gaiaAttributeFieldDoubleRange;
/**
Typedef for Attribute/Field Double range infos
\sa gaiaAttributeFieldDoubleRange
*/
typedef gaiaAttributeFieldDoubleRange *gaiaAttributeFieldDoubleRangePtr;
/**
LayerAttributeField infos
*/
typedef struct gaiaLayerAttributeFieldInfos
{
/** ordinal position */
int Ordinal;
/** SQL name of the corresponding column */
char *AttributeFieldName;
/** total count of NULL values */
int NullValuesCount;
/** total count of INTEGER values */
int IntegerValuesCount;
/** total count of DOUBLE values */
int DoubleValuesCount;
/** total count of TEXT values */
int TextValuesCount;
/** total count of BLOB values */
int BlobValuesCount;
/** pointer to MaxSize/Length infos (may be NULL) */
gaiaAttributeFieldMaxSizePtr MaxSize;
/** pointer to range of Integer values infos (may be NULL) */
gaiaAttributeFieldIntRangePtr IntRange;
/** pointer to range of Double values infos (may be NULL) */
gaiaAttributeFieldDoubleRangePtr DoubleRange;
/** pointer to next item (linked list) */
struct gaiaLayerAttributeFieldInfos *Next;
} gaiaLayerAttributeField;
/**
Typedef for Layer AttributeField infos
\sa gaiaLayerAttributeField
*/
typedef gaiaLayerAttributeField *gaiaLayerAttributeFieldPtr;
/**
Vector Layer item
*/
typedef struct gaiaVectorLayerItem
{
/** one of GAIA_VECTOR_UNKNOWN, GAIA_VECTOR_TABLE, GAIA_VECTOR_VIEW,
GAIA_VECTOR_VIRTUAL */
int LayerType;
/** SQL name of the corresponding table */
char *TableName;
/** SQL name of the corresponding Geometry column */
char *GeometryName;
/** SRID value */
int Srid;
/** one of GAIA_VECTOR_UNKNOWN, GAIA_VECTOR_POINT, GAIA_VECTOR_LINESTRING,
GAIA_VECTOR_POLYGON, GAIA_VECTOR_MULTIPOINT, GAIA_VECTOR_MULTILINESTRING,
GAIA_VECTOR_MULTIPOLYGON, GAIA_VECTOR_GEOMETRYCOLLECTION, GAIA_VECTOR_GEOMETRY
*/
int GeometryType;
/** one of GAIA_VECTOR_UNKNOWN, GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM */
int Dimensions;
/** one of GAIA_VECTOR_UNKNOWN, GAIA_SPATIAL_INDEX_NONE, GAIA_SPATIAL_INDEX_RTREE,
GAIA_SPATIAL_INDEX_MBRCACHE
*/
int SpatialIndex;
/** pointer to Extent infos (may be NULL) */
gaiaLayerExtentPtr ExtentInfos;
/** pointer to Auth infos (may be NULL) */
gaiaLayerAuthPtr AuthInfos;
/** pointer to first Field/Attribute (linked list) */
gaiaLayerAttributeFieldPtr First;
/** pointer to last Field/Attribute (linked list) */
gaiaLayerAttributeFieldPtr Last;
/** pointer to next item (linked list) */
struct gaiaVectorLayerItem *Next;
} gaiaVectorLayer;
/**
Typedef for Vector Layer item
\sa gaiaVectorLayer
*/
typedef gaiaVectorLayer *gaiaVectorLayerPtr;
/**
Container for Vector Layers List
*/
typedef struct gaiaVectorLayersListStr
{
/** pointer to first vector layer (linked list) */
gaiaVectorLayerPtr First;
/** pointer to last vector layer (linked list) */
gaiaVectorLayerPtr Last;
/** pointer to currently set vector layer */
gaiaVectorLayerPtr Current;
} gaiaVectorLayersList;
/**
Typedef for Vector Layers List
\sa gaiaVectorLayersList
*/
typedef gaiaVectorLayersList *gaiaVectorLayersListPtr;
/**
BBOX corresponding to PROJ.6 AREA
*/
typedef struct gaiaProjAreaStr
{
double WestLongitude;
double SouthLatitude;
double EastLongitude;
double NorthLatitude;
} gaiaProjArea;
/**
Typedef for BBOX corresponding to PROJ.6 AREA
\sa gaiaProjArea
*/
typedef gaiaProjArea *gaiaProjAreaPtr;
#ifdef __cplusplus
}
#endif
#endif /* _GG_STRUCTS_H */
libspatialite-5.1.0/src/headers/spatialite/gg_core.h 0000644 0001750 0001750 00000232100 14463127014 017403 0000000 0000000 /*
gg_core.h -- Gaia common support for geometries: core functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_core.h
Geometry handling functions: core
*/
#ifndef _GG_CORE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_CORE_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
#include
#else
#include
#endif
/* constant values for gaiaGeodesicArcLength return_type */
/** Arc Length measured in Degrees */
#define GAIA_GEODESIC_ARC_LENGTH_DEGREES 0
/** Arc Length measured in Meters */
#define GAIA_GEODESIC_ARC_LENGTH_METERS 1
/** Chord Length measured in Degrees */
#define GAIA_GEODESIC_CHORD_LENGTH_DEGREES 2
/** Chord Length measured in Meters */
#define GAIA_GEODESIC_CHORD_LENGTH_METERS 3
/** Central Angle measured in Radians */
#define GAIA_GEODESIC_CENTRAL_ANGLE_RADIANS 4
/** Central Angle measured in Degrees */
#define GAIA_GEODESIC_CENTRAL_ANGLE_DEGREES 5
/** Area of segment/arc measured in Square Meters */
#define GAIA_GEODESIC_ARC_AREA_METERS 6
/** Height of segment/arc in Meters */
#define GAIA_GEODESIC_ARC_HEIGHT_METERS 7
/* function prototypes */
/**
Safely frees any dynamic memory block allocated by the library itself
\param ptr pointer to dynamically allocated memory
\note on some platforms (most notably, Microsoft Windows) many different
runtime libraries may actually support the same process.
\n attempting to free() a memory block allocated by a different runtime
module may easily cause fatal memory corruption.
*/
GAIAGEO_DECLARE void gaiaFree (void *ptr);
/**
Allocates a 2D POINT [XY]
\param x the X coordinate.
\param y the Y coordinate.
\return the pointer to the newly created POINT object: NULL on failure
\sa gaiaFreePoint
\note you are responsible to destroy (before or after) any allocated
POINT, unless you've passed ownership of the POINT object to some
further object: in this case destroying the higher order object will
implicitly destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPointPtr gaiaAllocPoint (double x, double y);
/**
Allocates a 3D POINT [XYZ]
\param x the X coordinate.
\param y the Y coordinate.
\param z the Z coordinate.
\return the pointer to the newly created POINT object: NULL on failure
\sa gaiaFreePoint
\note you are responsible to destroy (before or after) any allocated
POINT, unless you've passed ownership of the POINT object to some
further object: in this case destroying the higher order object will
implicitly destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPointPtr gaiaAllocPointXYZ (double x, double y,
double z);
/**
Allocates a 2D POINT [XYM]
\param x the X coordinate.
\param y the Y coordinate.
\param m the M measure.
\return the pointer to the newly created POINT object: NULL on failure
\sa gaiaFreePoint
\note you are responsible to destroy (before or after) any allocated
POINT, unless you've passed ownership of the POINT object to some
further object: in this case destroying the higher order object will
implicitly destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPointPtr gaiaAllocPointXYM (double x, double y,
double m);
/**
Allocates a 3D POINT [XYZM]
\param x the X coordinate.
\param y the Y coordinate.
\param z the Z coordinate.
\param m the M measure.
\return the pointer to the newly created POINT object: NULL on failure
\sa gaiaFreePoint
\note you are responsible to destroy (before or after) any allocated
POINT, unless you've passed ownership of the POINT object to some
further object: in this case destroying the higher order object will
implicitly destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPointPtr gaiaAllocPointXYZM (double x, double y,
double z, double m);
/**
Destroys a POINT object
\param ptr pointer to the POINT object to be destroyed
\sa gaiaAllocPoint, gaiaAllocPointXYZ, gaiaAllocPointXYM, gaiaAllocPointXYZM
\note attempting to destroy any POINT object whose ownership has already
been transferred to some other (higher order) object is a serious
error, and will easily cause severe memory corruption.
*/
GAIAGEO_DECLARE void gaiaFreePoint (gaiaPointPtr ptr);
/**
Allocates a 2D LINESTRING [XY]
\param vert number of points [aka vertices] into the Linestring
\return the pointer to newly created LINESTRING object: NULL on failure
\sa gaiaFreeLinestring, gaiaLineSetPoint, gaiaLineGetPoint, gaiaSetPoint,
gaiaGetPoint
\note you are responsible to destroy (before or after) any allocated LINESTRING,
unless you've passed ownership of the LINESTRING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaLinestringPtr gaiaAllocLinestring (int vert);
/**
Allocates a 3D LINESTRING [XYZ]
\param vert number of points [aka vertices] into the Linestring
\return the pointer to newly created LINESTRING object: NULL on failure
\sa gaiaFreeLinestring, gaiaLineSetPoint, gaiaLineGetPoint, gaiaSetPointXYZ,
gaiaGetPointXYZ
\note you are responsible to destroy (before or after) any allocated LINESTRING,
unless you've passed ownership of the LINESTRING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaLinestringPtr gaiaAllocLinestringXYZ (int vert);
/**
Allocates a 2D LINESTRING [XYM]
\param vert number of points [aka vertices] into the Linestring
\return the pointer to newly created LINESTRING object: NULL on failure
\sa gaiaFreeLinestring, gaiaLineSetPoint, gaiaLineGetPoint, gaiaSetPointXYM,
gaiaGetPointXYM
\note you are responsible to destroy (before or after) any allocated LINESTRING,
unless you've passed ownership of the LINESTRING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaLinestringPtr gaiaAllocLinestringXYM (int vert);
/**
Allocates a 3D LINESTRING [XYZM]
\param vert number of points [aka vertices] into the Linestring
\return the pointer to newly created LINESTRING object: NULL on failure
\sa gaiaFreeLinestring, gaiaLineSetPoint, gaiaLineGetPoint, gaiaSetPointXYZM,
gaiaGetPointXYZM
\note you are responsible to destroy (before or after) any allocated LINESTRING,
unless you've passed ownership of the LINESTRING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaLinestringPtr gaiaAllocLinestringXYZM (int vert);
/**
Destroys a LINESTRING object
\param ptr pointer to the LINESTRING object to be destroyed
\sa gaiaAllocLinestring, gaiaAllocLinestringXYZ, gaiaAllocLinestringXYM,
gaiaAllocLinestringXYZM
\note attempting to destroy any LINESTRING object whose ownnership has already
been transferred to some other (higher order) object is a serious
error, and will easily cause severe memory corruption.
*/
GAIAGEO_DECLARE void gaiaFreeLinestring (gaiaLinestringPtr ptr);
/**
Copies coordinates between two LINESTRING objects
\param dst destination LINESTRING [output]
\param src origin LINESTRING [input]
\sa gaiaCopyLinestringCoordsReverse, gaiaCopyLinestringCoordsEx
\note both LINESTRING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyLinestringCoords (gaiaLinestringPtr dst,
gaiaLinestringPtr src);
/**
Copies coordinates between two LINESTRING objects
\param dst destination LINESTRING [output]
\param src origin LINESTRING [input]
\param z_no_data the default Z value
\parma m_no_data the default M value
\sa gaiaCopyLinestringCoords
\note both LINESTRING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyLinestringCoordsEx (gaiaLinestringPtr dst,
gaiaLinestringPtr src,
double z_no_data,
double m_no_data);
/**
Copies coordinates between two LINESTRING objects in reverse order
\param dst destination LINESTRING [output]
\param src origin LINESTRING [input]
\sa gaiaCopyLinestringCoords
\note both LINESTRING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyLinestringCoordsReverse (gaiaLinestringPtr
dst,
gaiaLinestringPtr
src);
/**
Allocates a 2D RING [XY]
\param vert number of points [aka vertices] into the Ring
\return the pointer to newly created RING object: NULL on failure
\sa gaiaFreeRing, gaiaRingSetPoint, gaiaRingGetPoint, gaiaSetPoint,
gaiaGetPoint
\note you are responsible to destroy (before or after) any allocated RING,
unless you've passed ownership of the RING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaAllocRing (int vert);
/**
Allocates a 3D RING [XYZ]
\param vert number of points [aka vertices] into the Ring
\return the pointer to newly created RING object: NULL on failure
\sa gaiaFreeRing, gaiaRingSetPoint, gaiaRingGetPoint, gaiaSetPointXYZ,
gaiaGetPointXYZ
\note you are responsible to destroy (before or after) any allocated RING,
unless you've passed ownership of the RING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaAllocRingXYZ (int vert);
/**
Allocates 2D RING [XYM]
\param vert number of points [aka vertices] into the Ring
\return the pointer to newly created RING object: NULL on failure
\sa gaiaFreeRing, gaiaRingSetPoint, gaiaRingGetPoint, gaiaSetPointXYM,
gaiaGetPointXYM
\note you are responsible to destroy (before or after) any allocated RING,
unless you've passed ownership of the RING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaAllocRingXYM (int vert);
/**
Allocates a 3D RING [XYZM]
\param vert number of points [aka vertices] into the Ring
\return the pointer to newly created RING object: NULL on failure
\sa gaiaFreeRing, gaiaRingSetPoint, gaiaRingGetPoint, gaiaSetPointXYZM,
gaiaSetPointXYZM
\note you are responsible to destroy (before or after) any allocated RING,
unless you've passed ownership of the RING object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaAllocRingXYZM (int vert);
/**
Destroys a RING object
\param ptr pointer to the RING object to be destroyed
\sa gaiaAllocRing, gaiaAllocRingXYZ, gaiaAllocRingXYM,
gaiaAllocRingXYZM
\note attempting to destroy any RING object whose ownership has already
been transferred to some other (higher order) object is a serious
error, and will easily cause severe memory corruption.
*/
GAIAGEO_DECLARE void gaiaFreeRing (gaiaRingPtr ptr);
/**
Copies coordinates between two RING objects
\param dst destination RING [output]
\param src origin RING [input]
\sa gaiaCopyRingCoordsReverse, gaiaCopyRingCoordEx
\note both RING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyRingCoords (gaiaRingPtr dst, gaiaRingPtr src);
/**
Copies coordinates between two RING objects
\param dst destination RING [output]
\param src origin RING [input]
\param z_no_data the default Z value
\param m_no_data the default M value
\sa gaiaCopyRingCoords
\note both RING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyRingCoordsEx (gaiaRingPtr dst, gaiaRingPtr src,
double z_no_data,
double m_no_data);
/**
Copies coordinates between two RING objects in reverse order
\param dst destination RING [output]
\param src origin RING [input]
\sa gaiaCopyRingCoords
\note both RING objects must have exactly the same number of points:
if dimensions aren't the same for both objects, then the appropriate
conversion will be silently applied.
*/
GAIAGEO_DECLARE void gaiaCopyRingCoordsReverse (gaiaRingPtr dst,
gaiaRingPtr src);
/**
Allocates a 2D POLYGON [XY]
\param vert number of points [aka vertices] into the Exterior Ring.
\param holes number of Interior Rings [0, if no Interior Ring is required].
\return the pointer to newly created POLYGON object: NULL on failure
\sa gaiaFreePolygon
\note you are responsible to destroy (before or after) any allocated POLYGON,
unless you've passed ownership of the POLYGON object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaAllocPolygon (int vert, int holes);
/**
Allocates a 3D POLYGON [XYZ]
\param vert number of points [aka vertices] into the Exterior Ring.
\param holes number of Interior Rings [0, if no Interior Ring is required].
\return the pointer to newly created POLYGON object: NULL on failure
\sa gaiaFreePolygon
\note you are responsible to destroy (before or after) any allocated POLYGON,
unless you've passed ownership of the POLYGON object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaAllocPolygonXYZ (int vert, int holes);
/**
Allocates a 2D POLYGON [XYM]
\param vert number of points [aka vertices] into the Exterior Ring.
\param holes number of Interior Rings [0, if no Interior Ring is required].
\return the pointer to newly created POLYGON object: NULL on failure
\sa gaiaFreePolygon
\note you are responsible to destroy (before or after) any allocated POLYGON,
unless you've passed ownership of the POLYGON object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaAllocPolygonXYM (int vert, int holes);
/**
Allocates a 3D POLYGON [XYZM]
\param vert number of points [aka vertices] into the Exterior Ring.
\param holes number of Interior Rings [may by 0, if no Interior Ring is required].
\return the pointer to newly created POLYGON object: NULL on failure
\sa gaiaFreePolygon
\note you are responsible to destroy (before or after) any allocated POLYGON,
unless you've passed ownership of the POLYGON object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaAllocPolygonXYZM (int vert, int holes);
/**
Allocates a POLYGON
\param ring pointer to a valid RING object: assumed to be the Polygon's
Exterior Ring.
\return the pointer to newly created POLYGON object: NULL on failure
\sa gaiaAllocRing, gaiaAllocRingXYZ, gaiaAllocRingXYM, gaiaAllocRingXYZM,
gaiaFreePolygon
\note you are responsible to destroy (before or after) any allocated POLYGON,
unless you've passed ownership of the POLYGON object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
\n Ownership of passed Ring object will be transferred to the
Polygon object being created.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaCreatePolygon (gaiaRingPtr ring);
/**
Destroys a POLYGON object
\param polyg pointer to the POLYGON object to be destroyed
\sa gaiaAllocPolygon, gaiaAllocPolygonXYZ, gaiaAllocPolygonXYM,
gaiaAllocPolygonXYZM, gaiaCreatePolygon
\note attempting to destroy any POLYGON object whose ownership has already
been transferred to some other (higher order) object is a serious
error, and will easily cause severe memory corruption.
\n Ownership of each RING object referenced by a POLYGON object always belongs
to the POLYGON itself, so destroying the POLYGON will surely destroy
any related RING as well.
*/
GAIAGEO_DECLARE void gaiaFreePolygon (gaiaPolygonPtr polyg);
/**
Allocates a 2D Geometry [XY]
\return the pointer to newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaAllocGeomColl (void);
/**
Allocates a 3D Geometry [XYZ]
\return the pointer to newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaAllocGeomCollXYZ (void);
/**
Allocates a 2D Geometry [XYM]
\return the pointer to newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaAllocGeomCollXYM (void);
/**
Allocates a 3D Geometry [XYZM]
\return the pointer to newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further
object: in this case destroying the higher order object will implicitly
destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaAllocGeomCollXYZM (void);
/**
Destroys a Geometry object
\param geom pointer to the Geometry object to be destroyed
\sa gaiaAllocGeomColl, gaiaAllocGeomCollXYZ, gaiaAllocGeomCollXYM,
gaiaAllocGeomCollXYZM
\note attempting to destroy any Geometry object whose ownership has already
been transferred to some other (higher order) object is a serious
error, and will easily cause severe memory corruption.
\n Ownership of each POINT, LINESTRING or POLYGON object referenced by a
Geometry object always belongs to the Geometry itself, so destroying the
Geometry will surely destroy any related elementary geometry item as well.
*/
GAIAGEO_DECLARE void gaiaFreeGeomColl (gaiaGeomCollPtr geom);
/**
Creates a new 2D Point [XY] object into a Geometry object
\param p pointer to the Geometry object
\param x X coordinate of the Point to be created
\param y X coordinate of the Point to be created
\note ownership of the newly created POINT object belongs to the Geometry
object.
*/
GAIAGEO_DECLARE void gaiaAddPointToGeomColl (gaiaGeomCollPtr p, double x,
double y);
/**
Creates a new 3D Point [XYZ] object into a Geometry object
\param p pointer to the Geometry object
\param x X coordinate of the Point to be created
\param y X coordinate of the Point to be created
\param z Z coordinate of the Point to be created
\note ownership of the newly created POINT object belongs to the Geometry
object.
*/
GAIAGEO_DECLARE void gaiaAddPointToGeomCollXYZ (gaiaGeomCollPtr p,
double x, double y,
double z);
/**
Creates a new 2D Point [XYM] object into a Geometry object
\param p pointer to the Geometry object
\param x X coordinate of the Point to be created
\param y X coordinate of the Point to be created
\param m M measure of the Point to be created
\note ownership of the newly created POINT object belongs to the Geometry
object.
*/
GAIAGEO_DECLARE void gaiaAddPointToGeomCollXYM (gaiaGeomCollPtr p,
double x, double y,
double m);
/**
Creates a new 3D Point [XYZM] object into a Geometry object
\param p pointer to the Geometry object
\param x X coordinate of the Point to be created
\param y X coordinate of the Point to be created
\param z Z coordinate of the Point to be created
\param m M measure of the Point to be created
\note ownership of the newly created POINT object belongs to the Geometry
object.
*/
GAIAGEO_DECLARE void gaiaAddPointToGeomCollXYZM (gaiaGeomCollPtr p,
double x, double y,
double z, double m);
/**
Creates a new Linestring object into a Geometry object
\param p pointer to the Geometry object.
\param vert number of points [aka vertices] into the Linestring.
\return the pointer to newly created Linestring: NULL on failure.
\note ownership of the newly created Linestring object belongs to the Geometry object.
\n the newly created Linestring will have the same dimensions as the Geometry has.
*/
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAddLinestringToGeomColl (gaiaGeomCollPtr p, int vert);
/**
Inserts an already existing Linestring object into a Geometry object
\param p pointer to the Geometry object.
\param line pointer to the Linestring object.
\note ownership of the Linestring object will be transferred to the
Geometry object.
*/
GAIAGEO_DECLARE void gaiaInsertLinestringInGeomColl (gaiaGeomCollPtr p,
gaiaLinestringPtr
line);
/**
Creates a new Polygon object into a Geometry object
\param p pointer to the Geometry object.
\param vert number of points [aka vertices] into the Polygon's Exterior Ring.
\param interiors number of Interiors Rings [0, if no Interior Ring is required]
\return the pointer to newly created Polygon: NULL on failure.
\note ownership of the newly created Polygon object belongs to the Geometry object.
\n the newly created Polygon will have the same dimensions as the Geometry has.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaAddPolygonToGeomColl (gaiaGeomCollPtr
p, int vert,
int interiors);
/**
Creates a new Polygon object into a Geometry object starting from an
already existing Ring object
\param p pointer to the Geometry object.
\param ring pointer to the Ring object [assumed to represent to Polygon's
Exterior Ring].
\return the pointer to the newly created Polygon object: NULL on failure.
\note ownership of the Ring object will be transferred to the
Polygon object, and the Polygon object ownerships belongs to the Geometry object.
\n the Polygon object will have the same dimensions as the Ring object has.
*/
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaInsertPolygonInGeomColl (gaiaGeomCollPtr p, gaiaRingPtr ring);
/**
Creates a new Interior Ring object into a Polygon object
\param p pointer to the Polygon object.
\param pos relative position index [first Interior Ring has index 0].
\param vert number of points (aka vertices) into the Ring.
\return the pointer to the newly created Ring object: NULL on failure.
\sa gaiaAllocPolygon, gaiaAllocPolygonXYZ, gaiaAllocPolygonXYM,
gaiaAllocPolygonXYZM
\note ownership of the Ring object belongs to the Polygon object.
\n the newly created Ring will have the same dimensions the Polygon has.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaAddInteriorRing (gaiaPolygonPtr p,
int pos, int vert);
/**
Inserts an already existing Ring object into a Polygon object
\param p pointer to the Polygon object
\param ring pointer to the Ring object
\sa gaiaAddRingToPolygon
\note ownership of the Ring object still remains to the calling procedure
(a duplicated copy of the original Ring will be inserted into the Polygon).
\n the newly created Polygon will have the same dimensions as the Ring has.
\n if required the Polygon's Interior Rings count could be increased.
*/
GAIAGEO_DECLARE void gaiaInsertInteriorRing (gaiaPolygonPtr p,
gaiaRingPtr ring);
/**
Inserts an already existing Ring object into a Polygon object
\param polyg pointer to the Polygon object
\param ring pointer to the Ring object
\sa gaiaInsertInteriorRing
\note ownership of the Ring object will be transferred to the Polygon object.
\n the newly created Polygon will have the same dimensions as the Ring has.
\n if required the Polygon's Interior Rings count could be increased.
*/
GAIAGEO_DECLARE void gaiaAddRingToPolyg (gaiaPolygonPtr polyg,
gaiaRingPtr ring);
/**
Duplicates a Linestring object
\param line pointer to Linestring object [origin].
\return the pointer to newly created Linestring object: NULL on failure.
\sa gaiaCloneRing, gaiaClonePolygon, gaiaCloneGeomColl,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollLinestrings,
gaiaCloneGeomCollPolygons, gaiaCloneLinestringSpecial
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaLinestringPtr gaiaCloneLinestring (gaiaLinestringPtr
line);
/**
Duplicates a Linestring object (special)
\param line pointer to Linestring object [origin].
\param mode one of GAIA_SAME_ORDER or GAIA_REVERSE_ORDER.
\return the pointer to newly created Linestring object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneGeomCollSpecial
\note if GAIA_REVERSE_ORDER is specified, then any vertex into the newly created
object will be in reverse order [first vertex will be last one, and last vertex
will be the first one]. In any other case this function will simply default to
gaiaCloneLinestring.
*/
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaCloneLinestringSpecial (gaiaLinestringPtr line, int mode);
/**
Duplicates a Ring object
\param ring pointer to Ring object [origin].
\return the pointer to newly created Ring object: NULL on failure.
\sa gaiaCloneLinestring, gaiaClonePolygon, gaiaCloneGeomColl,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollLinestrings,
gaiaCloneGeomCollPolygons, gaiaCloneRingSpecial
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaCloneRing (gaiaRingPtr ring);
/**
Duplicates a Ring object (special)
\param ring pointer to Ring object [origin].
\param mode one of GAIA_SAME_ORDER or GAIA_REVERSE_ORDER.
\return the pointer to newly created Ring object: NULL on failure.
\sa gaiaCloneRing, gaiaClonePolygonSpecial
\note if GAIA_REVERSE_ORDER is specified, then any vertex into the newly created
object will be in reverse order [first vertex will be last one, and last vertex
will be the first one]. In any other case this function will simply default to
gaiaCloneRing.
*/
GAIAGEO_DECLARE gaiaRingPtr gaiaCloneRingSpecial (gaiaRingPtr ring,
int mode);
/**
Duplicates a Polygon object
\param polyg pointer to Polygon object [origin].
\return the pointer to newly created Polygon object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneRing, gaiaCloneGeomColl,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollLinestrings,
gaiaCloneGeomCollPolygons, gaiaClonePolygonSpecial
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaClonePolygon (gaiaPolygonPtr polyg);
/**
Duplicates a Polygon object (special)
\param polyg pointer to Polygon object [origin].
\param mode one of GAIA_SAME_ORDER, GAIA_REVERSE_ORDER, or GAIA_LHR_ORDER.
\return the pointer to newly created Polygon object: NULL on failure.
\sa gaiaClonePolygon, gaiaCloneGeomCollSpecial
\note if GAIA_REVERSE_ORDER is specified, then any Ring into the newly created
object will be in reverse order. If GAIA_CW_ORDER is specified, any
Exterior Ring will have clockwise orientation, and any Interior Ring will have
counter-clockwise orientation. If GAIA_CCW_ORDER is specified, any
Exterior Ring will have counter-clockwise orientation, and any Interior Ring
will have clockwise orientation. In any other case this function will simply
default to gaiaClonePolygon.
*/
GAIAGEO_DECLARE gaiaPolygonPtr gaiaClonePolygonSpecial (gaiaPolygonPtr
polyg, int mode);
/**
Duplicates a Geometry object
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneRing, gaiaClonePolygon,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollLinestrings,
gaiaCloneGeomCollPolygons, gaiaCastGeomCollToXY, gaiaCastGeomCollToXYZ,
gaiaCastGeomCollToXYM, gaiaCastGeomCollToXYZM, gaiaExtractPointsFromGeomColl,
gaiaExtractLinestringsFromGeomColl, gaiaExtractPolygonsFromGeomColl,
gaiaMergeGeometries, gaiaCloneGeomCollSpecial
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCloneGeomColl (gaiaGeomCollPtr geom);
/**
Duplicates a Geometry object (special)
\param geom pointer to Geometry object [origin].
\param mode one of GAIA_SAME_ORDER, GAIA_REVERSE_ORDER or GAIA_LHR_ORDER.
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneLinestringSpecial, gaiaCloneRingSpecial, gaiaClonePolygonSpecial,
gaiaCloneGeomColl
\note if GAIA_REVERSE_ORDER is specified, then any Linestring and/or Ring into
the newly created object will be in reverse order. If GAIA_LHR_ORDER is specified
instead, any Polygong will have the Exterior Ring in clockwise orientation, and any
Interior Ring int counter-clockwise orientation. In any other case this function will
simply default to gaiaCloneGeomColl.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCloneGeomCollSpecial (gaiaGeomCollPtr
geom, int mode);
/**
Duplicates a Geometry object [Points only]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneRing, gaiaClonePolygon, gaiaCloneGeomColl,
gaiaCloneGeomCollLinestrings,
gaiaCloneGeomCollPolygons
\note the newly created object is an exact copy of the original one; except
in that only Point objects will be copied.
\n Caveat: an empty Geometry could be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCloneGeomCollPoints (gaiaGeomCollPtr
geom);
/**
Duplicates a Geometry object [Linestrings only]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneRing, gaiaClonePolygon, gaiaCloneGeomColl,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollPolygons
\note the newly created object is an exact copy of the original one; except
in that only Linestrings objects will be copied.
\n Caveat: an empty Geometry could be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomCollLinestrings (gaiaGeomCollPtr geom);
/**
Duplicates a Geometry object [Polygons only]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneLinestring, gaiaCloneRing, gaiaClonePolygon, gaiaCloneGeomColl,
gaiaCloneGeomCollPoints, gaiaCloneGeomCollLinestrings
\note the newly created object is an exact copy of the original one; except
in that only Polygons objects will be copied.
\n Caveat: an empty Geometry could be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCloneGeomCollPolygons (gaiaGeomCollPtr
geom);
/**
Duplicates a Geometry object [casting dimensions to 2D XY]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneGeomColl, gaiaCastGeomCollToXYZ,
gaiaCastGeomCollToXYM, gaiaCastGeomCollToXYZM
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be casted to 2D [XY] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXY (gaiaGeomCollPtr geom);
/**
Duplicates a Geometry object [casting dimensions to 3D XYZ]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneGeomColl, gaiaCastGeomCollToXY,
gaiaCastGeomCollToXYM, gaiaCastGeomCollToXYZM,
gaiaCostGeomCollToXYZnoData
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 3D [XYZ] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXYZ (gaiaGeomCollPtr
geom);
/**
Duplicates a Geometry object [casting dimensions to 2D XYM]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneGeomColl, gaiaCastGeomCollToXY, gaiaCastGeomCollToXYZ,
gaiaCastGeomCollToXYZM, gaiaCastGeomCollToXYMnoData
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 2D [XYM] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXYM (gaiaGeomCollPtr
geom);
/**
Duplicates a Geometry object [casting dimensions to 3D XYZM]
\param geom pointer to Geometry object [origin].
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCloneGeomColl, gaiaCastGeomCollToXY, gaiaCastGeomCollToXYZ,
gaiaCastGeomCollToXYM, gaiaCastGeomCollToXYZMnoData
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 3D [XYZM] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXYZM (gaiaGeomCollPtr
geom);
/**
Duplicates a Geometry object [casting dimensions to 3D XYZ - noData]
\param geom pointer to Geometry object [origin].
\param no_data the default Z value
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCostGeomCollToXYZ
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 3D [XYZ] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXYZnoData (gaiaGeomCollPtr
geom,
double
no_data);
/**
Duplicates a Geometry object [casting dimensions to 2D XYM - noData]
\param geom pointer to Geometry object [origin].
\param no_data the default M value
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCastGeomCollToXYM
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 2D [XYM] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCastGeomCollToXYMnoData (gaiaGeomCollPtr
geom,
double
no_data);
/**
Duplicates a Geometry object [casting dimensions to 3D XYZM - noData]
\param geom pointer to Geometry object [origin].
\param z_no_data the default Z value
\param m_no_data the default M value
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaCastGeomCollToXYZM
\note the newly created object is an exact copy of the original one; except
in that any elementary item will be cast to 3D [XYZM] dimensions.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYZMnoData (gaiaGeomCollPtr geom, double z_no_data,
double m_no_data);
/**
Gets coodinates from a Linestring's Point
\param ln pointer to Linestring object.
\param v relative position of Point: first Point has index 0
\param x on completion this variable will contain the Point X coordinate.
\param y on completion this variable will contain the Point Y coordinate.
\param z on completion this variable will contain the Point Z coordinate.
\param m on completion this variable will contain the Point M measure.
\return 0 on failure: any other different value on success.
\sa gaiaLineSetPoint, gaiaGetPoint, gaiaGetPointXYZ, gaiaGetPointXYM,
gaiaGetPointXYZM
\note this function perform the same identical task performed by
gaiaGetPoint(), gaiaGetPointXYZ(), gaiaGetPointXYM() and gaiaGetPointXYZM()
macros.
\n using the gaiaLineGetPoint() function is a little bit slower but is
intrinsically safest, because misused macros can easily cause severe
memory corruption.
\n gaiaLineGetPoint() instead will always ensure that the appropriate
dimensions (as declared by the Linestring object) will be correctly used.
*/
GAIAGEO_DECLARE int gaiaLineGetPoint (gaiaLinestringPtr ln, int v,
double *x, double *y, double *z,
double *m);
/**
Sets coordinates for a Linestring's Point
\param ln pointer to Linestring object.
\param v relative position of Point: first Point has index 0
\param x the Point's X coordinate.
\param y the Point's Y coordinate.
\param z the Point's Z coordinate.
\param m the Point's M measure.
\return 0 on failure: any other different value on success.
\sa gaiaLineGetPoint, gaiaSetPoint, gaiaSetPointXYZ, gaiaSetPointXYM,
gaiaSetPointXYZM
\note this function perform the same identical task performed by
gaiaSetPoint(), gaiaSetPointXYZ(), gaiaSetPointXYM() and gaiaSetPointXYZM()
macros.
\n using the gaiaLineSetPoint() function is a little bit slower but is
intrinsically safest, because misused macros can easily cause severe
memory corruption.
\n gaiaLineSetPoint() instead will always ensure that the appropriate
dimensions (as declared by the Linestring object) will be correctly used.
*/
GAIAGEO_DECLARE int gaiaLineSetPoint (gaiaLinestringPtr ln, int v,
double x, double y, double z,
double m);
/**
Gets coordinates from a Ring's Point
\param rng pointer to Ring object.
\param v relative position of Point: first Point has index 0
\param x on completion this variable will contain the Point X coordinate.
\param y on completion this variable will contain the Point Y coordinate.
\param z on completion this variable will contain the Point Z coordinate.
\param m on completion this variable will contain the Point M measure.
\return 0 on failure: any other different value on success.
\sa gaiaRingSetPoint, gaiaGetPoint, gaiaGetPointXYZ, gaiaGetPointXYM,
gaiaGetPointXYZM
\note this function perform the same identical task performed by
gaiaGetPoint(), gaiaGetPointXYZ(), gaiaGetPointXYM() and gaiaGetPointXYZM()
macros.
\n using the gaiaRingGetPoint() function is a little bit slower but is
intrinsically safest, because misused macros can easily cause severe
memory corruption.
\n gaiaRingGetPoint() instead will always ensure that the appropriate
dimensions (as declared by the Ring object) will be correctly used.
*/
GAIAGEO_DECLARE int gaiaRingGetPoint (gaiaRingPtr rng, int v, double *x,
double *y, double *z, double *m);
/**
Sets coodinates for a Ring's Point
\param rng pointer to Ring object.
\param v relative position of Point: first Point has index 0
\param x the Point's X coordinate.
\param y the Point's Y coordinate.
\param z the Point's Z coordinate.
\param m the Point's M measure.
\return 0 on failure: any other different value on success.
\sa gaiaRingGetPoint, gaiaGetPoint, gaiaGetPointXYZ, gaiaSetPointXYM,
gaiaSetPointXYZM
\note this function perform the same identical task performed by
gaiaSetPoint(), gaiaSetPointXYZ(), gaiaSetPointXYM() and gaiaSetPointXYZM()
macros.
\n using the gaiaRingSetPoint() function is a little bit slower but is
intrinsically safest, because misused macros can easily cause severe
memory corruption.
\n gaiaRingSetPoint() instead will always ensure that the appropriate
dimensions (as declared by the Ring object) will be correctly used.
*/
GAIAGEO_DECLARE int gaiaRingSetPoint (gaiaRingPtr rng, int v, double x,
double y, double z, double m);
/**
Determines OGC dimensions for a Geometry object
\param geom pointer to Geometry object
\return OGC dimensions
\note OGC dimensions are defined as follows:
\li if the Geometry doesn't contain any elementary item: \b -1
\li if the Geometry only contains Point items: \b 0
\li if the Geometry only contains Point / Linestring items: \b 1
\li if the Geometry contains some Polygon item: \b 2
*/
GAIAGEO_DECLARE int gaiaDimension (gaiaGeomCollPtr geom);
/**
Determines the corresponding Type for a Geometry object
\param geom pointer to Geometry object
\return the corresponding Geometry Type
\note Type is one of: GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON,
GAIA_MULTIPOINT, GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON,
GAIA_GEOMETRYCOLLECTION, GAIA_POINTZ, GAIA_LINESTRINGZ, GAIA_POLYGONZ,
GAIA_MULTIPOINTZ, GAIA_MULTILINESTRINGZ, GAIA_MULTIPOLYGONZ,
GAIA_GEOMETRYCOLLECTIONZ, GAIA_POINTM, GAIA_LINESTRINGM, GAIA_POLYGONM,
GAIA_MULTIPOINTM, GAIA_MULTILINESTRINGM, GAIA_MULTIPOLYGONM,
GAIA_GEOMETRYCOLLECTIONM, GAIA_POINTZM, GAIA_LINESTRINGZM, GAIA_POLYGONZM,
GAIA_MULTIPOINTZM, GAIA_MULTILINESTRINGZM, GAIA_MULTIPOLYGONZM,
GAIA_GEOMETRYCOLLECTIONZM
\n on failure GAIA_NONE will be returned.
*/
GAIAGEO_DECLARE int gaiaGeometryType (gaiaGeomCollPtr geom);
/**
Determines the corresponding Type for a Geometry object
\param geom pointer to Geometry object
\return the corresponding Geometry Type
\sa gaiaGeometryType
\note Type is one of: GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON,
GAIA_MULTIPOINT, GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON,
GAIA_GEOMETRYCOLLECTION
\n on failure GAIA_NONE will be returned.
\remark deprecated function (used in earlier SpatiaLite versions).
*/
GAIAGEO_DECLARE int gaiaGeometryAliasType (gaiaGeomCollPtr geom);
/**
Checks for empty Geometry object
\param geom pointer to Geometry object
\return 0 if the Geometry is not empty: otherwise any other different value.
\note an empty Geometry is a Geometry not containing any elementary
item: i.e. no Points, no Linestrings and no Polygons at all.
*/
GAIAGEO_DECLARE int gaiaIsEmpty (gaiaGeomCollPtr geom);
/**
Checks for Clockwise Geometry object
\param geom pointer to Geometry object
\return 0 if the Geometry is not clockwise: otherwise any other different value.
\note a Clockwise Geometry contains no Polygons, or alternatively
contains only Clockwise Polygons.
A Clockwise Polygon has a Clockwise exterior ring and all interior rings
are Counter-Clockwise.
*/
GAIAGEO_DECLARE int gaiaCheckClockwise (gaiaGeomCollPtr geom);
/**
Checks for CounterClockwise Geometry object
\param geom pointer to Geometry object
\return 0 if the Geometry is not counter-clockwise: otherwise any other different value.
\note a CounterClockwise Geometry contains no Polygons, or alternatively
contains only CounterClockwise Polygons.
A CounterClockwise Polygon has a CounterClockwise exterior ring and all
interior rings are Clockwise.
*/
GAIAGEO_DECLARE int gaiaCheckCounterClockwise (gaiaGeomCollPtr geom);
/**
Checks for toxic Geometry object
\param geom pointer to Geometry object
\return 0 if the Geometry is not toxic: otherwise any other different value.
\sa gaiaIsToxic_r, gaiaSanitize
\note a \b toxic Geometry is a Geometry containing severely malformed
Polygons: i.e. containing less than 4 Points.
\n Or containing severely malformed Linestrings: i.e. containing less
than 2 Points.
\n Attempting to pass any toxic Geometry to GEOS supported functions
will easily cause a crash.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE int gaiaIsToxic (gaiaGeomCollPtr geom);
/**
Checks for toxic Geometry object
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\return 0 if the Geometry is not toxic: otherwise any other different value.
\sa gaiaIsToxic, gaiaSanitize
\note a \b toxic Geometry is a Geometry containing severely malformed
Polygons: i.e. containing less than 4 Points.
\n Or containing severely malformed Linestrings: i.e. containing less
than 2 Points.
\n Attempting to pass any toxic Geometry to GEOS supported functions
will easily cause a crash.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE int gaiaIsToxic_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Checks for not-closed Rings
\param ring pointer to Ring object
\return 0 if the Ring in unclosed: otherwise any other different value.
\sa gaiaIsNotClosedRing_r, gaiaIsToxic, gaiaIsNotClosedGeomColl
\note unclosed Rings cause GEOS supported functions to crash.
\n SpatiaLite will always carefully check any Ring before passing it
to GEOS, eventually silently inserting a further point required so
to properly close the figure.
\n This function allows to explicitly identify any unclosed Ring.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE int gaiaIsNotClosedRing (gaiaRingPtr ring);
/**
Checks for not-closed Rings
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param ring pointer to Ring object
\return 0 if the Ring in unclosed: otherwise any other different value.
\sa gaiaIsNotClosedRing, gaiaIsToxic, gaiaIsNotClosedGeomColl
\note unclosed Rings cause GEOS supported functions to crash.
\n SpatiaLite will always carefully check any Ring before passing it
to GEOS, eventually silently inserting a further point required so
to properly close the figure.
\n This function allows to explicitly identify any unclosed Ring.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE int gaiaIsNotClosedRing_r (const void *p_data,
gaiaRingPtr ring);
/**
Checks for not-closed Rings in a Geometry object
\param geom pointer to Geometry object
\return 0 if the Geometry has no unclosed Rings: otherwise any other different value.
\sa gaiaIsNotClosedGeomColl_r, gaiaIsToxic, gaiaIsNotClosedRing
\note This function allows to explicitly identify any Geometry containing
at least one unclosed Ring.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE int gaiaIsNotClosedGeomColl (gaiaGeomCollPtr geom);
/**
Checks for not-closed Rings in a Geometry object
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\return 0 if the Geometry has no unclosed Rings: otherwise any other different value.
\sa gaiaIsNotClosedGeomColl, gaiaIsToxic, gaiaIsNotClosedRing
\note This function allows to explicitly identify any Geometry containing
at least one unclosed Ring.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE int gaiaIsNotClosedGeomColl_r (const void *p_data,
gaiaGeomCollPtr geom);
/**
Attempts to sanitize a possibly malformed Geometry object
\param org pointer to Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaIsToxic, gaiaEnsureClosedRings, gaiaRemoveRepeatedPoints
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaSanitize()
\n the output Geometry will surely have:
\li no repeated Points on Linestrings or Rings (i.e. consecutive Points
sharing exactly the same coordinates): any repeated Point will be suppressed,
simply leaving only the first occurrence.
\li proper Ring closure: for sure any Ring will have exactly coinciding
first and last Points.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSanitize (gaiaGeomCollPtr org);
/**
Attempts to sanitize a possibly malformed Geometry object
\param org pointer to Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaIsToxic, gaiaSanitize, gaiaRemoveRepeatedPoint
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaSanitize()
\n the output Geometry will surely have proper Ring closure: for sure any
Ring will have exactly coinciding first and last Points.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaEnsureClosedRings (gaiaGeomCollPtr org);
/**
Attempts to sanitize a possibly malformed Geometry object
\param org pointer to Geometry object.
\param tolerance
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaIsToxic, gaiaSanitizeGeometry, gaiaEnsureClosedRings
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaSanitize()
\n the output Geometry will surely have no repeated Points on Linestrings or Rings
or MultiPoints (i.e. consecutive Points sharing exactly the same coordinates or
falling within the given tolerace): any repeated Point will be suppressed,
simply leaving only the first occurrence.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaRemoveRepeatedPoints (gaiaGeomCollPtr
org,
double tolerance);
/**
Attempts to resolve a (Multi)Linestring from a Geometry object
\param geom pointer to Geometry object.
\param force_multi: 0 if the returned Geometry could represent a Linestring:
any other value if casting to MultiLinestring is required unconditionally.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaDissolveSegments, gaiaDissolvePoints
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaLinearize()
\n the input Geometry is expected to contain Polygons only: then any Ring
will be transformed into the corresponding Linestring.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLinearize (gaiaGeomCollPtr geom,
int force_multi);
/**
Attempts to resolve a collection of Segments from a Geometry object
\param geom pointer to Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaLinearize, gaiaDissolvePoints
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaDissolveSegments()
\n the input Geometry can be of any arbitrary type:
\li any Point will be copied untouched.
\li any Linestring will be dissolved into Segments.
\li any Ring will be dissolved into Segments.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDissolveSegments (gaiaGeomCollPtr geom);
/**
Attempts to resolve a collection of Points from a Geometry object
\param geom pointer to Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaLinearize, gaiaDissolveSegments
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaDissolvePoints()
\n the input Geometry can be of any arbitrary type:
\li any Point will be copied untouched.
\li any Linestring will be dissolved into sparse Points.
\li any Ring will be dissolved into sparse Points.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDissolvePoints (gaiaGeomCollPtr geom);
/**
Extracts any Point from a Geometry object
\param geom pointer to Geometry object
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaExtractLinestringsFromGeomColl,
gaiaExtractPolygonsFromGeomColl, gaiaCloneGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaExtractPointsFromGeomColl()
\n the newly created Geometry will contain any Point contained into the
input Geometry.
\n if the input Geometry doesn't contains any Point, then NULL will be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractPointsFromGeomColl (gaiaGeomCollPtr geom);
/**
Extracts any Linestring from a Geometry object
\param geom pointer to Geometry object
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaExtractPointsFromGeomColl, gaiaExtractPolygonsFromGeomColl,
gaiaCloneGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaExtractLinestringsFromGeomColl()
\n the newly created Geometry will contain any Linestring contained into the
input Geometry.
\n if the input Geometry doesn't contains any Linestring, then NULL will be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractLinestringsFromGeomColl (gaiaGeomCollPtr geom);
/**
Extracts any Polygon from a Geometry object
\param geom pointer to Geometry object
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaExtractPointsFromGeomColl, gaiaExtractLinestringsFromGeomColl,
gaiaCloneGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaExtractPolygonsFromGeomColl()
\n the newly created Geometry will contain any Polygon contained into the
input Geometry.
\n if the input Geometry doesn't contains any Polygon, then NULL will be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractPolygonsFromGeomColl (gaiaGeomCollPtr geom);
/**
Merges two Geometry objects into a single one
\param geom1 pointer to first Geometry object.
\param geom2 pointer to second Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaMergeGeometries_r, gaiaCloneGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaMergeGeometries()
\n the newly created Geometry will contain any Point, Linestring and/or
Polygon contained in both input Geometries.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMergeGeometries (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr geom2);
/**
Merges two Geometry objects into a single one
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object.
\param geom2 pointer to second Geometry object.
\return the pointer to newly created Geometry: NULL on failure.
\sa gaiaMergeGeometries, gaiaCloneGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaMergeGeometries()
\n the newly created Geometry will contain any Point, Linestring and/or
Polygon contained in both input Geometries.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMergeGeometries_r (const void
*p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Will return a new GEOMETRY (supporting M) with measures linearly
interpolated between the start and end points.
\param geom pointer to Geometry object of the Linestring or MultiLinestring type.
\param m_start M start value
\param m_end M end value
\return the pointer to newly created Geometry: NULL on failure.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaAddMeasure()
\n the newly created Geometry will contain Linestrings.
\n if the input Geometry has no M dimension it will be added, otherwise
it will overwritten.
\n an eventual Z will be preserved unaffected.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAddMeasure (gaiaGeomCollPtr geom, double m_start, double m_end);
#ifndef OMIT_GEOS /* including GEOS */
/**
Will interpolate the M-value for a LinestringM at the point closest to the
given Point.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param line pointer to Geometry object of the Linestring type and supporting
the M dimension.
\param point pointer to Geometry object of the Point type.
\param m_value on succesfull completion this variable will contain the
interpolated M value
\return 0 on failure: any other value on success.
*/
GAIAGEO_DECLARE int
gaiaInterpolatePoint (const void *p_cache, gaiaGeomCollPtr line,
gaiaGeomCollPtr point, double *m_value);
#endif /* end including GEOS */
/**
Return a GeometryCollection containing elements matching the specified range of measures
\param geom pointer to Geometry object
\param m_start range of measures: start value
\param m_end range of measures: end value
\return the pointer to newly created Geometry: NULL on failure.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry created by gaiaLocateBetweenMeasures()
\n the newly created Geometry will contain Points and/or Linestrings.
\n if the input Geometry has no M dimension then NULL will be returned.
\n if the input Geometry doesn't contains any point/vertex corresponding to the
required range of measures then NULL will be returned.
\n if the input Geometry contains any Polygon (or is a GeometryCollection) then
NULL will be returned.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLocateBetweenMeasures (gaiaGeomCollPtr geom, double m_start,
double m_end);
/**
Checks if a Geometry object is valid Trajectory
\param geom pointer to Geometry object
\return 0 if false; any other value if true
\sa gaiaTrajectoryInterpolatePoint
\note a Geometry is considered to be a valid Trajectory if it contains
a simple LINESTRING supporting M-values growing from each vertex to the next.
*/
GAIAGEO_DECLARE int gaiaIsValidTrajectory (gaiaGeomCollPtr geom);
/**
Attempts to interpolate a Point along a Trajectory accordingly to given M-Value
\param geom pointer to Geometry object (expected to be a valid Trajectory)
\param m the M-Value to be interpolated
\return the pointer to newly created Geometry object representing a Point
laying on the input Geometry and positioned at the given M-Value
NULL on failure.
\sa gaiaIsValidTrajectory, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaTrajectoryInterpolatePoint()\n
not reentrant and thread unsafe.
\note a Geometry is considered to be a valid Trajectory if it contains
a simple LINESTRING supporting M-values growing from each vertex to the next.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTrajectoryInterpolatePoint (gaiaGeomCollPtr geom, double m);
/**
Measures the geometric length for a Linestring or Ring
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_ZM
\param coords pointed to COORD mem-array
\param vert number of Points (aka Vertices) within the COORD mem-array
\return the calculated geometric length
\sa gaiaGeomCollLength
\note \b dims, \b coords and \b vert are usually expected to correspond to
\b DimensionModel, \b Coords and \b Points members from a gaiaLinestringStruct
or gaiaRingStruct
\remark internal method: doesn't require any GEOS support.
*/
GAIAGEO_DECLARE double gaiaMeasureLength (int dims, double *coords,
int vert);
/**
Measures the geometric area for a Ring object
\param ring pointer to Ring object
\return the calculated geometric area
\sa gaiaGeomCollArea
\remark internal method: doesn't require any GEOS support.
*/
GAIAGEO_DECLARE double gaiaMeasureArea (gaiaRingPtr ring);
/**
Determines the Centroid for a Ring object
\param ring pointer to Ring object.
\param rx on completion this variable will contain the centroid X coordinate.
\param ry on completion this variable will contain the centroid Y coordinate.
\sa gaiaGeomCollCentroid
\remark internal method: doesn't require any GEOS support.
*/
GAIAGEO_DECLARE void gaiaRingCentroid (gaiaRingPtr ring, double *rx,
double *ry);
/**
Determines the direction for a Ring object
\param p pointer to Ring object
\return 0 if the ring has counter-clockwise direction; any other different
value for clockwise direction.
*/
GAIAGEO_DECLARE void gaiaClockwise (gaiaRingPtr p);
/**
Check if a Point lays on a Ring surface
\param ring pointer to Ring object
\param pt_x Point X coordinate
\param pt_y Point Y coordinate
\return 0 if false: any other value if true
*/
GAIAGEO_DECLARE int gaiaIsPointOnRingSurface (gaiaRingPtr ring,
double pt_x, double pt_y);
/**
Checks if a Point lays on a Polygon surface
\param polyg pointer to Polygon object
\param x Point X coordinate
\param y Point Y coordinate
\return 0 if false: any other value if true
*/
GAIAGEO_DECLARE int gaiaIsPointOnPolygonSurface (gaiaPolygonPtr polyg,
double x, double y);
/**
Computes the minimum distance between a Point and a Linestring or Ring
\param x0 Point X coordinate
\param y0 Point Y coordinate
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_ZM
\param coords pointed to COORD mem-array
\param vert number of Points (aka Vertices) within the COORD mem-array
\return the calculated minumum distance.
\note \b dims, \b coords and \b vert are usually expected to correspond to
\b DimensionModel, \b Coords and \b Points members from a gaiaLinestringStruct
or gaiaRingStruct
*/
GAIAGEO_DECLARE double gaiaMinDistance (double x0, double y0,
int dims, double *coords, int vert);
/**
Determines the intesection Point between two Segments
\param x0 on completion this variable will contain the Intersection X coord
\param y0 on completion this variable will contain the Intersection Y coord
\param x1 start Point X of first Segment
\param y1 start Point Y of first Segment
\param x2 end Point X of first Segment
\param y2 end Point Y of first Segment
\param x3 start Point X of second Segment
\param y3 start Point Y of second Segment
\param x4 end Point X of second Segment
\param y4 end Point Y of second Segment
\return 0 if the Segments doesn't intersect at all: any other value on
success.
*/
GAIAGEO_DECLARE int gaiaIntersect (double *x0, double *y0, double x1,
double y1, double x2, double y2,
double x3, double y3, double x4,
double y4);
/**
Shifts any coordinate within a Geometry object
\param geom pointer to Geometry object.
\param shift_x X axis shift factor.
\param shift_y Y axis shift factor.
\sa gaiaScaleCoords, gaiaRotateCoords, gaiaReflectCoords, gaiaSwapCoords,
gaiaShiftCoords3D, gaiaShiftLongitude
*/
GAIAGEO_DECLARE void gaiaShiftCoords (gaiaGeomCollPtr geom,
double shift_x, double shift_y);
/**
Shifts any coordinate within a 3D Geometry object
\param geom pointer to Geometry object.
\param shift_x X axis shift factor.
\param shift_y Y axis shift factor.
\param shift_z Z axis shift factor.
\sa gaiaScaleCoords, gaiaRotateCoords, gaiaReflectCoords, gaiaSwapCoords,
gaiaShiftCoords, gaiaShiftLongitude, gaiaNormalizeLonLat
*/
GAIAGEO_DECLARE void gaiaShiftCoords3D (gaiaGeomCollPtr geom,
double shift_x, double shift_y,
double shift_z);
/**
Shifts negative longitudes
\param geom pointer to Geometry object.
\sa gaiaShiftCoords, gaiaShiftCoords3D, gaiaNormalizeLonLat
\note only intended for geographic (longitude/latitude) coordinates.
Negative longitudes (-180/0) will be shifted by 360, thus allowing
to represent longitudes in the 0/360 range and effectively crossing
the International Date Line.
*/
GAIAGEO_DECLARE void gaiaShiftLongitude (gaiaGeomCollPtr geom);
/**
Shifts any coordinate to within the "normal range" of longitude and
latitude values (-180.0 to 180.0 longitude and -90.0 to 90.0 latitude).
\param geom pointer to Geometry object.
\sa gaiaScaleCoords, gaiaRotateCoords, gaiaReflectCoords, gaiaSwapCoords,
gaiaShiftCoords3D, gaiaShiftLongitude
*/
GAIAGEO_DECLARE void gaiaNormalizeLonLat (gaiaGeomCollPtr geom);
/**
Scales any coordinate within a Geometry object
\param geom pointer to Geometry object.
\param scale_x X axis scale factor.
\param scale_y Y axis scale factor.
\sa gaiaShiftCoords, gaiaRotateCoords, gaiaReflectCoords, gaiaSwapCoords
*/
GAIAGEO_DECLARE void gaiaScaleCoords (gaiaGeomCollPtr geom,
double scale_x, double scale_y);
/**
Rotates any coordinate within a Geometry object
\param geom pointer to Geometry object.
\param angle rotation angle [expressed in Degrees].
\sa gaiaShiftCoords, gaiaScaleCoords, gaiaReflectCoords, gaiaSwapCoords
*/
GAIAGEO_DECLARE void gaiaRotateCoords (gaiaGeomCollPtr geom, double angle);
/**
Reflects any coordinate within a Geometry object
\param geom pointer to Geometry object.
\param x_axis if set to 0, no X axis reflection will be applied:
otherwise the X axis will be reflected.
\param y_axis if set to 0, no Y axis reflection will be applied:
otherwise the Y axis will be reflected.
\sa gaiaShiftCoords, gaiaScaleCoords, gaiaRotateCoords, gaiaSwapCoords
*/
GAIAGEO_DECLARE void gaiaReflectCoords (gaiaGeomCollPtr geom, int x_axis,
int y_axis);
/**
Swaps any coordinate within a Geometry object
\param geom pointer to Geometry object.
\sa gaiaShiftCoords, gaiaScaleCoords, gaiaRotateCoords, gaiaReflectCoords
\note the X and Y axes will be swapped.
*/
GAIAGEO_DECLARE void gaiaSwapCoords (gaiaGeomCollPtr geom);
/**
Checks if two Linestring objects are equivalent
\param line1 pointer to first Linestring object.
\param line2 pointer to second Linestring object.
\return 0 if false: any other different value if true
\sa gaiaPolygonEquals
\note two Linestrings objects are assumed to be equivalent if exactly
\remark deprecated function (used in earlier SpatiaLite versions).
the same Points are found in both them.
*/
GAIAGEO_DECLARE int gaiaLinestringEquals (gaiaLinestringPtr line1,
gaiaLinestringPtr line2);
/**
Checks if two Polygons objects are equivalent
\param polyg1 pointer to first Polygon object.
\param polyg2 pointer to second Polygon object.
\return 0 if false: any other different value if true
\sa gaiaLinestringEquals
\note two Polygon objects are assumed to be equivalent if exactly
the same Points are found in both them.
\remark deprecated function (used in earlier SpatiaLite versions).
*/
GAIAGEO_DECLARE int gaiaPolygonEquals (gaiaPolygonPtr polyg1,
gaiaPolygonPtr polyg2);
/**
Retrieves Geodesic params for an Ellipsoid definition
\param name text string identifying an Ellipsoid definition.
\param a on completion this variable will contain the first geodesic param.
\param b on completion this variable will contain the second geodesic param.
\param rf on completion this variable will contain the third geodesic param.
\return 0 on failure: any other value on success.
\sa gaiaGreatCircleDistance, gaiaGeodesicDistance,
gaiaGreatCircleTotalLength, gaiaGeodesicTotalLength
\note supported Ellipsoid definitions are: \b MERIT, \b SGS85, \b GRS80,
\b IAU76, \b airy, \b APL4.9, \b NWL9D, \b mod_airy, \b andrae, \b aust_SA,
\b GRS67, \b bessel, \b bess_nam, \b clrk66, \b clrk80, \b CPM, \b delmbr,
\b engelis, \b evrst30, \b evrst48, \b evrst56, \b evrst69, \b evrstSS,
\b fschr60
*/
GAIAGEO_DECLARE int gaiaEllipseParams (const char *name, double *a,
double *b, double *rf);
/**
Calculates the Great Circle Distance between between two Points
\param a first geodesic parameter.
\param b second geodesic parameter.
\param lat1 Latitude of first Point.
\param lon1 Longitude of first Point.
\param lat2 Latitude of second Point.
\param lon2 Longitude of second Point.
\return the calculated Great Circle Distance.
\sa gaiaEllipseParams, gaiaGeodesicDistance,
gaiaGreatCircleTotalLength, gaiaGeodesicTotalLength
\note the returned distance is expressed in Kilometers.
\n the Great Circle method is less accurate but fastest to be calculated.
*/
GAIAGEO_DECLARE double gaiaGreatCircleDistance (double a, double b,
double lat1, double lon1,
double lat2, double lon2);
/**
Calculates the Geodesic Distance between two Points
\param a first geodesic parameter.
\param b second geodesic parameter.
\param rf third geodesic parameter.
\param lat1 Latitude of first Point.
\param lon1 Longitude of first Point.
\param lat2 Latitude of second Point.
\param lon2 Longitude of second Point.
\return the calculated Geodesic Distance.
\sa gaiaEllipseParams, gaiaGreatCircleDistance, gaiaGreatCircleTotalLength,
gaiaGeodesicTotalLength, gaiaGeodesicArcLength
\note the returned distance is expressed in Kilometers.
\n the Geodesic method is much more accurate but slowest to be calculated.
*/
GAIAGEO_DECLARE double gaiaGeodesicDistance (double a, double b,
double rf, double lat1,
double lon1, double lat2,
double lon2);
/**
Calculates the Great Circle Total Length for a Linestring / Ring
\param a first geodesic parameter.
\param b second geodesic parameter.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_ZM
\param coords pointed to COORD mem-array
\param vert number of Points (aka Vertices) within the COORD mem-array
\return the calculated Great Circle Total Length.
\sa gaiaEllipseParams, gaiaGreatCircleDistance, gaiaGeodesicDistance,
gaiaGeodesicTotalLength
\note the returned length is expressed in Kilometers.
\n the Great Circle method is less accurate but fastest to be calculated.
\n \b dims, \b coords and \b vert are usually expected to correspond to
\b DimensionModel, \b Coords and \b Points members from a gaiaLinestringStruct
or gaiaRingStruct
*/
GAIAGEO_DECLARE double gaiaGreatCircleTotalLength (double a, double b,
int dims,
double *coords,
int vert);
/**
Calculates the Geodesic Total Length for a Linestring / Ring
\param a first geodesic parameter.
\param b second geodesic parameter.
\param rf third geodesic parameter.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_ZM
\param coords pointed to COORD mem-array
\param vert number of Points (aka Vertices) within the COORD mem-array
\return the calculated Geodesic Total Length.
\sa gaiaEllipseParams, gaiaGreatCircleDistance, gaiaGeodesicDistance,
gaiaGreatCircleTotalLength, gaiaGeodesicArcLength
\note the returned length is expressed in Kilometers.
\n the Geodesic method is much more accurate but slowest to be calculated.
\n \b dims, \b coords and \b vert are usually expected to correspond to
\b DimensionModel, \b Coords and \b Points members from a gaiaLinestringStruct
or gaiaRingStruct.
*/
GAIAGEO_DECLARE double gaiaGeodesicTotalLength (double a, double b,
double rf, int dims,
double *coords, int vert);
/**
Convert a Length from a Measure Unit to another
\param value the length measure to be converted.
\param unit_from original Measure Unit.
\param unit_to converted Measure Unit.
\param cvt on completion this variable will contain the converted length
measure.
\note supported Measu Units are: GAIA_KM, GAIA_M, GAIA_DM, GAIA_CM, GAIA_MM,
GAIA_KMI, GAIA_IN, GAIA_FT, GAIA_YD, GAIA_MI, GAIA_FATH, GAIC_CH, GAIA_LINK,
GAIA_US_IN, GAIA_US_FT, GAIA_US_YD, GAIA_US_CH, GAIA_US_MI, GAIA_IND_YD,
GAIA_IND_FT, GAIA_IND_CH
*/
GAIAGEO_DECLARE int gaiaConvertLength (double value, int unit_from,
int unit_to, double *cvt);
/**
Computes several Geodesic values based on the Distance between two Geometries
\param db_handle handle to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param geom1 the first Geometry.
\param geom2 the second Geometry.
\param return_type selects wich value has be computed.
Must be one between: GAIA_GEODESIC_ARC_LENGTH_METERS,
GAIA_GEODESIC_ARC_LENGTH_DEGREES, GAIA_GEODESIC_CHORD_LENGTH_METERS,
GAIA_GEODESIC_CHORD_LENGTH_DEGREES, GAIA_GEODESIC_CENTRAL_ANGLE_DEGREES,
GAIA_GEODESIC_CENTRAL_ANGLE_RADIANS, GAIA_GEODESIC_ARC_AREA_METERS or
GAIA_GEODESIC_ARC_HEIGHT_METERS.
\param retval on completion this variable will contain the computed value.
\return 0 on failure: any other value on success.
\sa gaiaGeodesicDistance, gaiaGeodesicTotalLength
\note Both geom1 and geom2 must share the same SRID, that is expected
to be of the Geographic type (longitudes and latitudes).
\n Requires to be supported by a recent version of PROJ (>= 4.9.0).
\n If not supported by GEOS only two POINT Geometries will be accepted.
*/
GAIAGEO_DECLARE int gaiaGeodesicArcLength (sqlite3 * sqlite,
const void *cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
int return_type, double *retval);
/**
Creates a Circle (Linestring) Geometry
\param center_x center point X coordinate.
\param center_y center point Y coordinate.
\param radius the circle's radius.
\param step angular distance (in degrees) between points on the circumference.
\sa gaiaMakeArc, gaiaMakeEllipse, gaiaMakeEllipticArc
\note simply a convenience method defaulting to gaiaMakeEllipse
with both axes set to radius value
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeCircle (double center_x,
double center_y,
double radius, double step);
/**
Creates an Ellipse (Linestring) Geometry
\param center_x center point X coordinate.
\param center_y center point Y coordinate.
\param x_axis the ellipses's X axis.
\param y_axis the ellipses's Y axis.
\param step angular distance (in degrees) between points on the ellipse.
\sa gaiaMakeEllipticArc, gaiaMakeCircle, gaiaMakeArc
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeEllipse (double center_x,
double center_y,
double x_axis,
double y_axis,
double step);
/**
Creates a Circular Arc (Linestring) Geometry
\param center_x center point X coordinate.
\param center_y center point Y coordinate.
\param radius the circle's radius.
\param start the start angle (in degrees).
\param start the stop angle (in degrees).
\param step angular distance (in degrees) between points on the circumference.
\sa gaiaMakeCircle, gaiaMakeEllipse, gaiaMakeEllipticArc
\note simply a convenience method defaulting to gaiaMakeEllipticArc
with both axes set to radius value
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeArc (double center_x,
double center_y,
double radius, double start,
double stop, double step);
/**
Creates an Elliptic Arc (Linestring) Geometry
\param center_x center point X coordinate.
\param center_y center point Y coordinate.
\param x_axis the ellipses's X axis.
\param y_axis the ellipses's Y axis.
\param start the start angle (in degrees).
\param start the stop angle (in degrees).
\param step angular distance (in degrees) between points on the ellipse.
\sa gaiaMakeCircle, gaiaMakeEllipse, gaiaMakeEllipticArc
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeEllipticArc (double center_x,
double center_y,
double x_axis,
double y_axis,
double start,
double stop,
double step);
/**
Creates a Polygon from closed Linestrings
\param exterior a closed Linestring assumed to represent the Exterior Ring.
\param interiors one (or more than one) clsed Linestrings assumed to represent
all Interior Rings (could be a Linstring or a MultiLinestring).\n
NULL if there are no Interior Rings at all.
\sa gaiaPolygonize
\note this method will simply check if all the received Linestrings are
closed, but it could possibly return an invalid Polygon if there is any
topology inconsistency between the exterior and interior rings.
You are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaPolygonize()\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakePolygon (gaiaGeomCollPtr exterior,
gaiaGeomCollPtr interiors);
/**
Computes the Curvosity Index for some Linestrings
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param line a generic Linestring.
\param extra_points number of points to be interpolated at regular
distance into the reference line.
\return the calculated Curvosity Index (expected to be in the range between 0.0 and 1.0).
*/
GAIAGEO_DECLARE double gaiaCurvosityIndex (const void *p_cache,
gaiaLinestringPtr line,
int extra_points);
/**
Computes the Uphill and Downhill total Height for some 3D Linestrings
\param line a generic Linestring.
\param up on completion this variable will contain the total Uphill Height.\n
Will always be ZERO for any 2D Linestring.
\param down on completion this variable will contain the total Downhill Height.\n
Will always be ZERO for any 2D Linestring.
*/
GAIAGEO_DECLARE void gaiaUpDownHeight (gaiaLinestringPtr line, double *up,
double *down);
#ifdef _WIN32
GAIAGEO_DECLARE FILE * gaia_win_fopen(const char *path, const char *mode);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _GG_CORE_H */
libspatialite-5.1.0/src/headers/spatialite/gg_mbr.h 0000644 0001750 0001750 00000044704 14463127014 017246 0000000 0000000 /*
gg_mbr.h -- Gaia common support for geometries: MBR functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_mbr.h
Geometry handling functions: MBR
*/
#ifndef _GG_MBR_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_MBR_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* function prototypes */
/**
Updates the actual MBR for a Linestring object
\param line pointer to the Linestring object
*/
GAIAGEO_DECLARE void gaiaMbrLinestring (gaiaLinestringPtr line);
/**
Updates the actual MBR for a Ring object
\param rng pointer to the Ring object
*/
GAIAGEO_DECLARE void gaiaMbrRing (gaiaRingPtr rng);
/**
Updates the actual MBR for a Polygon object
\param polyg pointer to the Polygon object
*/
GAIAGEO_DECLARE void gaiaMbrPolygon (gaiaPolygonPtr polyg);
/**
Updates the actual MBR for a Geometry object
\param geom pointer to the Geometry object
*/
GAIAGEO_DECLARE void gaiaMbrGeometry (gaiaGeomCollPtr geom);
/**
Retrieves the MBR (MinX) from a BLOB-Geometry object
\param blob pointer to BLOB-Geometry.
\param size the BLOB's size (in bytes).
\param minx on completion this variable will contain the MBR MinX coordinate.
\return 0 on failure: any other value on success.
\sa gaiaGetMbrMaxX, gaiaGetMbrMinY, gaiaGetMbrMaxY
*/
GAIAGEO_DECLARE int gaiaGetMbrMinX (const unsigned char *blob,
unsigned int size, double *minx);
/**
Retrieves the MBR (MaxX) from a BLOB-Geometry object
\param blob pointer to BLOB-Geometry.
\param size the BLOB's size (in bytes).
\param maxx on completion this variable will contain the MBR MaxX coordinate.
\return 0 on failure: any other value on success.
\sa gaiaGetMbrMinX, gaiaGetMbrMinY, gaiaGetMbrMaxY
*/
GAIAGEO_DECLARE int gaiaGetMbrMaxX (const unsigned char *blob,
unsigned int size, double *maxx);
/**
Retrieves the MBR (MinY) from a BLOB-Geometry object
\param blob pointer to BLOB-Geometry.
\param size the BLOB's size (in bytes).
\param miny on completion this variable will contain the MBR MinY coordinate.
\return 0 on failure: any other value on success.
\sa gaiaGetMbrMinX, gaiaGetMbrMaxX, gaiaGetMbrMaxY
*/
GAIAGEO_DECLARE int gaiaGetMbrMinY (const unsigned char *blob,
unsigned int size, double *miny);
/**
Retrieves the MBR (MaxY) from a BLOB-Geometry object
\param blob pointer to BLOB-Geometry.
\param size the BLOB's size (in bytes).
\param maxy on completion this variable will contain the MBR MaxY coordinate.
\return 0 on failure: any other value on success.
\sa gaiaGetMbrMinX, gaiaGetMbrMaxX, gaiaGetMbrMinY
*/
GAIAGEO_DECLARE int gaiaGetMbrMaxY (const unsigned char *blob,
unsigned int size, double *maxy);
/**
Creates a Geometry object corresponding to the Envelope [MBR] for a
BLOB-Geometry
\param blob pointer to BLOB-Geometry
\param size the BLOB's size (in bytes)
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromSpatiaLiteBlobMbr (const unsigned
char *blob,
unsigned int
size);
/**
MBRs comparison: Contains
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 spatially \e contains mbr2
\sa gaiaMbrsDisjoint, gaiaMbrsEqual, gaiaMbrsIntersects,
gaiaMbrsOverlaps, gaiaMbrsTouches, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsContains (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Disjoint
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 and mbr2 are spatially \e disjoint
\sa gaiaMbrsContains, gaiaMbrsEqual, gaiaMbrsIntersects,
gaiaMbrsOverlaps, gaiaMbrsTouches, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsDisjoint (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Equal
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 and mbr2 are spatially \e equal
\sa gaiaMbrsContains, gaiaMbrsDisjoint, gaiaMbrsIntersects,
gaiaMbrsOverlaps, gaiaMbrsTouches, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsEqual (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Intersects
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 and mbr2 spatially \e intersect
\sa gaiaMbrsContains, gaiaMbrsDisjoint, gaiaMbrsEqual,
gaiaMbrsOverlaps, gaiaMbrsTouches, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsIntersects (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Overlaps
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 and mbr2 spatially \e overlap
\sa gaiaMbrsContains, gaiaMbrsDisjoint, gaiaMbrsEqual, gaiaMbrsIntersects,
gaiaMbrsTouches, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsOverlaps (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Touches
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 and mbr2 spatially \e touche
\sa gaiaMbrsContains, gaiaMbrsDisjoint, gaiaMbrsEqual, gaiaMbrsIntersects,
gaiaMbrsOverlaps, gaiaMbrsWithin
*/
GAIAGEO_DECLARE int gaiaMbrsTouches (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
MBRs comparison: Within
\param mbr1 pointer to first Geometry object.
\param mbr2 pointer to second Geometry object.
\return 0 if false; any other value if mbr1 is spatially \e within mbr2
\sa gaiaMbrsContains, gaiaMbrsDisjoint, gaiaMbrsEqual, gaiaMbrsIntersects,
gaiaMbrsOverlaps, gaiaMbrsTouches
*/
GAIAGEO_DECLARE int gaiaMbrsWithin (gaiaGeomCollPtr mbr1,
gaiaGeomCollPtr mbr2);
/**
Creates a BLOB-Geometry representing an Envelope [MBR]
\param x1 first X coordinate.
\param y1 first Y coordinate.
\param x2 second X coordinate.
\param y2 second Y coordinate.
\param srid the SRID associated to the Envelope
\param result on completion will contain a pointer to newly created
BLOB-Geometry
\param size on completion this variabile will contain the BLOB's size (in
bytes)
\sa gaiaBuildCircleMbr
\note [XY] coords must define two extreme Points identifying a diagonal
of the MBR [Envelope]
\n no special order is required for coords: MAX / MIN values will be
internally arranged as appropriate.
*/
GAIAGEO_DECLARE void gaiaBuildMbr (double x1, double y1, double x2,
double y2, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing an Envelope [MBR]
\param x centre X coordinate.
\param y centre Y coordinate.
\param radius the radius of the circle
\param srid the SRID associated to the Envelope
\param result on completion will contain a pointer to newly created
BLOB-Geometry
\param size on completion this variabile will contain the BLOB's size (in
bytes)
\sa gaiaBuildMbr
\note the \e circle of givern \e radius and \e centre will be used so to
determine the corresponding \e square Envelope
*/
GAIAGEO_DECLARE void gaiaBuildCircleMbr (double x, double y,
double radius, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-FilterMBR
\param x1 first X coordinate.
\param y1 first Y coordinate.
\param x2 second X coordinate.
\param y2 second Y coordinate.
\param mode one of: GAIA_FILTER_MBR_WITHIN, GAIA_FILTER_MBR_CONTAINS,
GAIA_FILTER_MBR_INTERSECTS, GAIA_FILTER_MBR_DECLARE
\param result on completion will contain a pointer to newly created
BLOB-FilterMBR
\param size on completion this variabile will contain the BLOB's size (in
bytes)
\sa gaiaParseFilterMbr
\note [XY] coords must define two extreme Points identifying a diagonal
of the MBR [Envelope]
\n no special order is required for coords: MAX / MIN values will be
internally arranged as appropriate.
\remark internally used to implement Geometry Callback R*Tree filtering.
*/
GAIAGEO_DECLARE void gaiaBuildFilterMbr (double x1, double y1, double x2,
double y2, int mode,
unsigned char **result, int *size);
/**
Creates a BLOB-FilterMBR
\param result pointer to BLOB-FilterMBR [previously created by
gaiaBuildFilterMbr]
BLOB-Geometry
\param size BLOB's size (in bytes)
\param minx on completion this variable will contain the MBR MinX coord.
\param miny on completion this variable will contain the MBR MinY coord.
\param maxx on completion this variable will contain the MBR MinY coord.
\param maxy on completion this variable will contain the MBR MaxY coord.
\param mode on completion this variable will contain the FilterMBR mode.
\sa gaiaBuildFilterMbr
\remark internally used to implement Geometry Callback R*Tree filtering.
*/
GAIAGEO_DECLARE int gaiaParseFilterMbr (unsigned char *result, int size,
double *minx, double *miny,
double *maxx, double *maxy,
int *mode);
/**
Computes the Z-Range for a Linestring object
\param line pointer to the Linestring object
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeLinestringEx
\note if the Linestring has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeLinestring (gaiaLinestringPtr line,
double *min, double *max);
/**
Computes the Z-Range for a Linestring object (NODATA flavor)
\param line pointer to the Linestring object
\param nodata the NODATA value
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeLinestring
\note if the Linestring has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeLinestringEx (gaiaLinestringPtr line,
double nodata, double *min,
double *max);
/**
Computes the Z-Range for a Ring object
\param rng pointer to the Ring object
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeRingEx
\note if the Ring has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeRing (gaiaRingPtr rng, double *min,
double *max);
/**
Computes the Z-Range for a Ring object (NODATA flavor)
\param rng pointer to the Ring object
\param nodata the NODATA value
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeRing
\note if the Ring has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeRingEx (gaiaRingPtr rng, double nodata,
double *min, double *max);
/**
Computes the Z-Range for a Polygon object
\param polyg pointer to the Polygon object
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangePolygonEx
\note if the Polygon has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangePolygon (gaiaPolygonPtr polyg, double *min,
double *max);
/**
Computes the Z-Range for a Polygon object (NODATA flavor)
\param polyg pointer to the Polygon object
\param nodata the NODATA value
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangePolygon
\note if the Polygon has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangePolygonEx (gaiaPolygonPtr polyg,
double nodata, double *min,
double *max);
/**
Computes the Z-Range for a Geometry object
\param geom pointer to the Geometry object
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeGeometryEx
\note if the Geometry has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeGeometry (gaiaGeomCollPtr geom,
double *min, double *max);
/**
Computes the Z-Range for a Geometry object (NODATA flavor)
\param geom pointer to the Geometry object
\param nodata the NODATA value
\param min on completion this variable will contain the min Z value found
\param max on completion this variable will contain the max Z value found
\sa gaiaZRangeGeometry
\note if the Geometry has XY or XYM dims, the Z-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaZRangeGeometryEx (gaiaGeomCollPtr geom,
double nodata, double *min,
double *max);
/**
Computes the M-Range for a Linestring object
\param line pointer to the Linestring object
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeLinestringEx
\note if the Linestring has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeLinestring (gaiaLinestringPtr line,
double *min, double *max);
/**
Computes the M-Range for a Linestring object (NODATA flavor)
\param line pointer to the Linestring object
\param nodata the NODATA value
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeLinestring
\note if the Linestring has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeLinestringEx (gaiaLinestringPtr line,
double nodata, double *min,
double *max);
/**
Computes the M-Range for a Ring object
\param rng pointer to the Ring object
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeRingEx
\note if the Ring has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeRing (gaiaRingPtr rng, double *min,
double *max);
/**
Computes the M-Range for a Ring object (NODATA flavor)
\param rng pointer to the Ring object
\param nodata the NODATA value
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeRing
\note if the Ring has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeRingEx (gaiaRingPtr rng, double nodata,
double *min, double *max);
/**
Computes the M-Range for a Polygon object
\param polyg pointer to the Polygon object
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangePolygonEx
\note if the Polygon has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangePolygon (gaiaPolygonPtr polyg, double *min,
double *max);
/**
Computes the M-Range for a Polygon object (NODATA flavor)
\param polyg pointer to the Polygon object
\param nodata the NODATA value
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangePolygon
\note if the Polygon has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangePolygonEx (gaiaPolygonPtr polyg,
double nodata, double *min,
double *max);
/**
Computes the Z-Range for a Geometry object
\param geom pointer to the Geometry object
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeGeometryEx
\note if the Geometry has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeGeometry (gaiaGeomCollPtr geom,
double *min, double *max);
/**
Computes the Z-Range for a Geometry object (NODATA flavor)
\param geom pointer to the Geometry object
\param nodata the NODATA value
\param min on completion this variable will contain the min M value found
\param max on completion this variable will contain the max M value found
\sa gaiaMRangeGeometryEx
\note if the Geometry has XY or XYZ dims, the M-Range is meaningless
*/
GAIAGEO_DECLARE void gaiaMRangeGeometryEx (gaiaGeomCollPtr geom,
double nodata, double *min,
double *max);
#ifdef __cplusplus
}
#endif
#endif /* _GG_MBR_H */
libspatialite-5.1.0/src/headers/spatialite/gg_formats.h 0000644 0001750 0001750 00000212613 14463127014 020135 0000000 0000000 /*
gg_formats.h -- Gaia common support for geometries: formats
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Klaus Foerster klaus.foerster@svg.cc
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_formats.h
Geometry handling functions: formats
*/
#ifndef _GG_FORMATS_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_FORMATS_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* function prototypes */
/**
Test CPU endianness
\return 0 if big-endian: any other value if little-endian
*/
GAIAGEO_DECLARE int gaiaEndianArch (void);
/**
Import an INT-16 value in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal SHORT value
\sa gaiaEndianArch, gaiaExport16
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 2 bytes.
*/
GAIAGEO_DECLARE short gaiaImport16 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Import an INT-32 value in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal INT value
\sa gaiaEndianArch, gaiaExport32
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE int gaiaImport32 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Import an UINT-32 value in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal UINT value
\sa gaiaEndianArch, gaiaExportU32
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE unsigned int gaiaImportU32 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Import a FLOAT-32 value in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal FLOAT value
\sa gaiaEndianArch, gaiaExportF32
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE float gaiaImportF32 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Import an DOUBLE-64 in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal DOUBLE value
\sa gaiaEndianArch, gaiaExport64
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 8 bytes.
*/
GAIAGEO_DECLARE double gaiaImport64 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Import an INT-64 in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal INT-64 value
\sa gaiaEndianArch, gaiaExportI64
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 8 bytes.
*/
GAIAGEO_DECLARE sqlite3_int64 gaiaImportI64 (const unsigned char *p,
int little_endian,
int little_endian_arch);
/**
Export an INT-16 value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImport16
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 2 bytes.
*/
GAIAGEO_DECLARE void gaiaExport16 (unsigned char *p, short value,
int little_endian,
int little_endian_arch);
/**
Export an INT-32 value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImport32
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE void gaiaExport32 (unsigned char *p, int value,
int little_endian,
int little_endian_arch);
/**
Export an UINT-32 value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImportU32
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE void gaiaExportU32 (unsigned char *p, unsigned int value,
int little_endian,
int little_endian_arch);
/**
Export a FLOAT-32 value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImportF32
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 4 bytes.
*/
GAIAGEO_DECLARE void gaiaExportF32 (unsigned char *p, float value,
int little_endian,
int little_endian_arch);
/**
Export a DOUBLE value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImport64
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 8 bytes.
*/
GAIAGEO_DECLARE void gaiaExport64 (unsigned char *p, double value,
int little_endian,
int little_endian_arch);
/**
Export an INT-64 value in endian-aware fashion
\param p endian-dependent representation (output buffer).
\param value the internal value to be exported.
\param little_endian 0 if the output buffer has to be big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\sa gaiaEndianArch, gaiaImportI64
\note you are expected to pass an output buffer corresponding to an
allocation size of (at least) 8 bytes.
*/
GAIAGEO_DECLARE void gaiaExportI64 (unsigned char *p, sqlite3_int64 value,
int little_endian,
int little_endian_arch);
/**
Initializes a dynamically growing Text output buffer
\param buf pointer to gaiaOutBufferStruct structure
\sa gaiaOutBufferReset, gaiaAppendToOutBuffer
\note Text notations representing Geometry objects may easily require
a huge storage amount: the gaiaOutBufferStruct automatically supports
a dynamically growing output buffer.
\n You are required to initialize this structure before attempting
any further operation;
and you are responsible to cleanup any related memory allocation
when it's any longer required.
*/
GAIAGEO_DECLARE void gaiaOutBufferInitialize (gaiaOutBufferPtr buf);
/**
Resets a dynamically growing Text output buffer to its initial (empty) state
\param buf pointer to gaiaOutBufferStruct structure
\sa gaiaOutBufferInitialize, gaiaAppendToOutBuffer
\note You are required to initialize this structure before attempting
any further operation:
this function will release any related memory allocation.
*/
GAIAGEO_DECLARE void gaiaOutBufferReset (gaiaOutBufferPtr buf);
/**
Appends a text string at the end of Text output buffer
\param buf pointer to gaiaOutBufferStruct structure.
\param text the text string to be appended.
\sa gaiaOutBufferInitialize, gaiaOutBufferReset
\note You are required to initialize this structure before attempting
any further operation:
the dynamically growing Text buffer will be automatically allocated
and/or extended as required.
*/
GAIAGEO_DECLARE void gaiaAppendToOutBuffer (gaiaOutBufferPtr buf,
const char *text);
/**
Creates a BLOB-Geometry representing a Point (BLOB-Geometry)
\param x Point X coordinate.
\param y Point Y coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointEx
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePoint (double x, double y, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing a PointZ (BLOB-Geometry)
\param x Point X coordinate.
\param y Point Y coordinate.
\param z Point Z coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointZEx
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointZ (double x, double y, double z,
int srid, unsigned char **result,
int *size);
/**
Creates a BLOB-Geometry representing a PointM (BLOB-Geometry)
\param x Point X coordinate.
\param y Point Y coordinate.
\param m Point M coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointMEx
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointM (double x, double y, double m,
int srid, unsigned char **result,
int *size);
/**
Creates a BLOB-Geometry representing a PointZM (BLOB-Geometry)
\param x Point X coordinate.
\param y Point Y coordinate.
\param z Point Z coordinate.
\param m Point M coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointZMEx
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointZM (double x, double y, double z,
double m, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing a Point (BLOB-Geometry or BLOB-TinyPoint)
\param tiny_point if set to TRUE the POINT Geometry will be encoded
by using the TinyPoint BLOB format.
\param x Point X coordinate.
\param y Point Y coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePoint
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointEx (int tiny_point, double x, double y,
int srid, unsigned char **result,
int *size);
/**
Creates a BLOB-Geometry representing a PointZ (BLOB-Geometry or BLOB-TinyPoint)
\param tiny_point if set to TRUE the POINT Geometry will be encoded
by using the TinyPoint BLOB format.
\param x Point X coordinate.
\param y Point Y coordinate.
\param z Point Z coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointZ
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointZEx (int tiny_point, double x, double y,
double z, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing a PointM (BLOB-Geometry or BLOB-TinyPoint)
\param tiny_point if set to TRUE the POINT Geometry will be encoded
by using the TinyPoint BLOB format.
\param x Point X coordinate.
\param y Point Y coordinate.
\param m Point M coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointM
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointMEx (int tiny_point, double x, double y,
double m, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing a PointZM (BLOB-Geometry or BLOB-TinyPoint)
\param tiny_point if set to TRUE the POINT Geometry will be encoded
by using the TinyPoint BLOB format.
\param x Point X coordinate.
\param y Point Y coordinate.
\param z Point Z coordinate.
\param m Point M coordinate.
\param srid the SRID to be set for the Point.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaMakePointZM
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakePointZMEx (int tiny_point, double x, double y,
double z, double m, int srid,
unsigned char **result, int *size);
/**
Creates a BLOB-Geometry representing a Segment (2-Points Linestring)
\param geom1 pointer to first Geometry object (expected to represent a Point).
\param geom2 pointer to second Geometry object (expected to represent a Point).
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaMakeLine (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
unsigned char **result, int *size);
/**
Creates a Geometry object from the corresponding BLOB-Geometry
\param blob pointer to BLOB-Geometry
\param size the BLOB's size
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl, gaiaToSpatiaLiteBlobWkb, gaiaToCompressedBlobWkb,
gaiaFromSpatiaLiteBlobWkbEx
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromSpatiaLiteBlobWkb (const unsigned
char *blob,
unsigned int
size);
/**
Creates a Geometry object from the corresponding BLOB-Geometry
\param blob pointer to BLOB-Geometry
\param size the BLOB's size
\param gpkg_mode is set to TRUE will accept only GPKG Geometry-BLOBs
\param gpkg_amphibious is set to TRUE will indifferenctly accept
either SpatiaLite Geometry-BLOBs or GPKG Geometry-BLOBs
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaFreeGeomColl, gaiaToSpatiaLiteBlobWkb, gaiaToCompressedBlobWkb
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromSpatiaLiteBlobWkbEx (const
unsigned char
*blob,
unsigned int
size,
int
gpkg_mode,
int
gpkg_amphibious);
/**
Creates a BLOB-Geometry corresponding to a Geometry object
\param geom pointer to the Geometry object.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaToCompressedBlobWkb
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToSpatiaLiteBlobWkb (gaiaGeomCollPtr geom,
unsigned char **result,
int *size);
/**
Creates a BLOB-Geometry corresponding to a Geometry object
\param geom pointer to the Geometry object.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\param gpkg_mode if set to TRUE will always return GPKG Geometry-BLOBs
\sa gaiaFromSpatiaLiteBlobWkb, gaiaToCompressedBlobWkb,
gaiaToSpatiaLiteBlobWkbEx2
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToSpatiaLiteBlobWkbEx (gaiaGeomCollPtr geom,
unsigned char **result,
int *size, int gpkg_mode);
/**
Creates a BLOB-Geometry corresponding to a Geometry object
\param geom pointer to the Geometry object.
\param result on completion will containt a pointer to BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\param gpkg_mode if set to TRUE will always return GPKG Geometry-BLOBs
\param tiny_point if set to TRUE all POINT Geometries will be encoded
by using the TinyPoint BLOB format.
\sa gaiaFromSpatiaLiteBlobWkb, gaiaToCompressedBlobWkb,
gaiaToSpatiaLiteBlobWkbEx
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToSpatiaLiteBlobWkbEx2 (gaiaGeomCollPtr geom,
unsigned char **result,
int *size, int gpkg_mode,
int tiny_point);
/**
Creates a Compressed BLOB-Geometry corresponding to a Geometry object
\param geom pointer to the Geometry object.
\param result on completion will containt a pointer to Compressed BLOB-Geometry:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromSpatiaLiteBlobWkb, gaiaToSpatiaLiteBlobWkb
\note this function will apply compression to any Linestring / Ring found
within the Geometry to be encoded.
\n the returned BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToCompressedBlobWkb (gaiaGeomCollPtr geom,
unsigned char **result,
int *size);
/**
Creates a Geometry object from WKB notation
\param blob pointer to WKB buffer
\param size the BLOB's size (in bytes)
\return the pointer to the newly created Geometry object: NULL on failure.
\sa gaiaToWkb, gaiaToHexWkb, gaiaFromEWKB, gaiaToEWKB
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromWkb (const unsigned char *blob,
unsigned int size);
/**
Encodes a Geometry object into WKB notation
\param geom pointer to Geometry object
\param result on completion will containt a pointer to the WKB buffer [BLOB]:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\sa gaiaFromWkb, gaiaToHexWkb, gaiaFromEWKB, gaiaToEWKB
\note this function will apply 3D WKB encoding as internally intended by
SpatiaLite: not necessarily intended by other OGC-like implementations.
\n Anyway, 2D WKB is surely standard and safely interoperable.
\n the returned BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToWkb (gaiaGeomCollPtr geom,
unsigned char **result, int *size);
/**
Encodes a Geometry object into (hex) WKB notation
\param geom pointer to Geometry object
\return the pointer to a text buffer containing WKB translated into plain
hexadecimal: NULL on failure.
\sa gaiaFromWkb, gaiaToWkb, gaiaFromEWKB, gaiaToEWKB
\note the returned buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE char *gaiaToHexWkb (gaiaGeomCollPtr geom);
/**
Encodes a Geometry object into EWKB notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\sa gaiaFromWkb, gaiaToWkb, gaiaToHexWkb, gaiaFromEWKB, gaiaToEWKB
\note this function will produce strictly conformat EWKB; you can
safely use this for PostGIS data exchange.
*/
GAIAGEO_DECLARE void gaiaToEWKB (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom);
/**
Creates a Geometry object from EWKB notation
\param in_buffer pointer to EWKB buffer
\return the pointer to the newly created Geometry object: NULL on failure.
\sa gaiaToWkb, gaiaToHexWkb, gaiaParseHexEWKB, gaiaToEWKB, gaiaEwkbGetPoint,
gaiaEwkbGetLinestring, gaiaEwkbGetPolygon, gaiaEwkbGetMultiGeometry
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromEWKB (const unsigned char
*in_buffer);
/**
Translates an EWKB notation from hexadecimal into binary
\param blob_hex pointer to EWKB input buffer (hexadecimal text string)
\param blob_size lenght (in bytes) of the input buffer; if succesfull will
contain the lenght of the returned output buffer.
\return the pointer to the newly created EWKB binary buffer: NULL on failure.
\sa gaiaToWkb, gaiaToHexWkb, gaiaFromEWKB, gaiaToEWKB
\note you are responsible to destroy (before or after) any buffer allocated by
gaiaParseHexEWKB()
*/
GAIAGEO_DECLARE unsigned char *gaiaParseHexEWKB (const unsigned char
*blob_hex, int *blob_size);
/**
Attempts to decode a Point from within an EWKB binary buffer
\param geom pointer to an existing Geometry object; if succesfull the parsed Point
will be inserted into this Geometry
\param blob pointer to EWKB input buffer
\param offset the offset (in bytes) on the input buffer where the Point definition is expected to start.
\param blob_size lenght (in bytes) of the input buffer.
\param endian (boolean) states if the EWKB input buffer is little- or big-endian encode.
\param endian_arch (boolean) states if the target CPU has a little- or big-endian architecture.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_Z_M
\return -1 on failure; otherwise the offset where the next object starts.
\sa gaiaEwkbGetLinestring, gaiaEwkbGetPolygon, gaiaEwkbGetMultiGeometry
\note these functions are mainly intended for internal usage.
*/
GAIAGEO_DECLARE int
gaiaEwkbGetPoint (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims);
/**
Attempts to decode a Point from within an EWKB binary buffer
\param geom pointer to an existing Geometry object; if succesfull the parsed Linestring
will be inserted into this Geometry
\param blob pointer to EWKB input buffer
\param offset the offset (in bytes) on the input buffer where the Point definition is expected to start.
\param blob_size lenght (in bytes) of the input buffer.
\param endian (boolean) states if the EWKB input buffer is little- or big-endian encode.
\param endian_arch (boolean) states if the target CPU has a little- or big-endian architecture.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_Z_M
\return -1 on failure; otherwise the offset where the next object starts.
\sa gaiaEwkbGetPoint, gaiaEwkbGetPolygon, gaiaEwkbGetMultiGeometry
\note these functions are mainly intended for internal usage.
*/
GAIAGEO_DECLARE int
gaiaEwkbGetLinestring (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims);
/**
Attempts to decode a Polygon from within an EWKB binary buffer
\param geom pointer to an existing Geometry object; if succesfull the parsed Polygon
will be inserted into this Geometry
\param blob pointer to EWKB input buffer
\param offset the offset (in bytes) on the input buffer where the Point definition is expected to start.
\param blob_size lenght (in bytes) of the input buffer.
\param endian (boolean) states if the EWKB input buffer is little- or big-endian encode.
\param endian_arch (boolean) states if the target CPU has a little- or big-endian architecture.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_Z_M
\return -1 on failure; otherwise the offset where the next object starts.
\sa gaiaEwkbGetPoint, gaiaEwkbGetPolygon, gaiaEwkbGetMultiGeometry
*/
GAIAGEO_DECLARE int
gaiaEwkbGetPolygon (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims);
/**
Attempts to decode a MultiGeometry from within an EWKB binary buffer
\param geom pointer to an existing Geometry object; if succesfull the parsed MultiGeometry
will be inserted into this Geometry
\param blob pointer to EWKB input buffer
\param offset the offset (in bytes) on the input buffer where the Point definition is expected to start.
\param blob_size lenght (in bytes) of the input buffer.
\param endian (boolean) states if the EWKB input buffer is little- or big-endian encode.
\param endian_arch (boolean) states if the target CPU has a little- or big-endian architecture.
\param dims dimensions: one of GAIA_XY, GAIA_XY_Z, GAIA_XY_M or GAIA_XY_Z_M
\return -1 on failure; otherwise the offset where the next object starts.
\sa gaiaEwkbGetPoint, gaiaEwkbGetLinestring, gaiaEwkbGetPolygon
\note these functions are mainly intended for internal usage.
*/
GAIAGEO_DECLARE int
gaiaEwkbGetMultiGeometry (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims);
/**
Creates a Geometry object from FGF notation
\param blob pointer to FGF buffer
\param size the BLOB's size (in bytes)
\return the pointer to the newly created Geometry object: NULL on failure.
\sa gaiaToFgf
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromFgf (const unsigned char *blob,
unsigned int size);
/**
Encodes a Geometry object into FGF notation
\param geom pointer to Geometry object
\param result on completion will containt a pointer to the FGF buffer [BLOB]:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes)
\param coord_dims one of: GAIA_XY, GAIA_XY_Z, GAIA_XY_M, GAIA_XY_ZM
\sa gaiaFromFgf
\note the returned BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaToFgf (gaiaGeomCollPtr geom,
unsigned char **result, int *size,
int coord_dims);
/**
Creates a Geometry object from WKT notation
\param in_buffer pointer to WKT buffer
\param type the expected Geometry Class Type
\n if actual type defined in WKT doesn't corresponds to this, an error will
be raised.
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaOutWkt, gaiaOutWktStrict, gaiaParseEWKT, gaiaToEWKT
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseWkt (const unsigned char
*in_buffer, short type);
/**
Encodes a Geometry object into WKT notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\sa gaiaParseWkt, gaiaOutWktStrict, gaiaParseEWKT, gaiaToEWKT,
gaiaOutWktEx
\note this function will apply 3D WKT encoding as internally intended by
SpatiaLite: not necessarily intended by other OGC-like implementations.
\n Anyway, 2D WKT is surely standard and safely interoperable.
*/
GAIAGEO_DECLARE void gaiaOutWkt (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom);
/**
Encodes a Geometry object into WKT notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\param precision decimal digits to be used for coordinates
\sa gaiaParseWkt, gaiaOutWktStrict, gaiaParseEWKT, gaiaToEWKT
\note this function will apply 3D WKT encoding as internally intended by
SpatiaLite: not necessarily intended by other OGC-like implementations.
\n Anyway, 2D WKT is surely standard and safely interoperable.
*/
GAIAGEO_DECLARE void gaiaOutWktEx (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom, int precision);
/**
Encodes a Geometry object into strict 2D WKT notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\param precision decimal digits to be used for coordinates
\sa gaiaParseWkt, gaiaOutWkt, gaiaParseEWKT, gaiaToEWKT
\note this function will apply strict 2D WKT encoding, so to be surely
standard and safely interoperable.
\n Dimensions will be automatically casted to 2D [XY] when required.
*/
GAIAGEO_DECLARE void gaiaOutWktStrict (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom, int precision);
/**
Creates a Geometry object from EWKT notation
\param in_buffer pointer to EWKT buffer
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaParseWkt, gaiaOutWkt, gaiaOutWktStrict, gaiaToEWKT
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseEWKT (const unsigned char
*in_buffer);
/**
Encodes a Geometry object into EWKT notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\sa gaiaParseWkt, gaiaOutWkt, gaiaOutWktStrict, gaiaParseEWKT
\note this function will apply PostGIS own EWKT encoding.
*/
GAIAGEO_DECLARE void gaiaToEWKT (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom);
/**
Encodes a WKT 3D Point [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param point pointer to Point object
\sa gaiaOutLinestringZ, gaiaOutPolygonZ, gaiaOutPointZex
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutPointZ (gaiaOutBufferPtr out_buf,
gaiaPointPtr point);
/**
Encodes a WKT 3D Point [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param point pointer to Point object
\param precision decimal digits to be used for coordinates
\sa gaiaOutLinestringZ, gaiaOutPolygonZ
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutPointZex (gaiaOutBufferPtr out_buf,
gaiaPointPtr point, int precision);
/**
Encodes a WKT 3D Linestring [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param linestring pointer to Linestring object
\sa gaiaOutPointZ, gaiaOutPolygonZ, gaiaOutLinestringZex
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutLinestringZ (gaiaOutBufferPtr out_buf,
gaiaLinestringPtr linestring);
/**
Encodes a WKT 3D Linestring [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param linestring pointer to Linestring object
\param precision decimal digits to be used for coordinates
\sa gaiaOutPointZ, gaiaOutPolygonZ
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutLinestringZex (gaiaOutBufferPtr out_buf,
gaiaLinestringPtr linestring,
int precision);
/**
Encodes a WKT 3D Polygon [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param polygon pointer to Point object
\sa gaiaOutPointZ, gaiaOutLinestringZ, gaiaOutPolygonZex
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutPolygonZ (gaiaOutBufferPtr out_buf,
gaiaPolygonPtr polygon);
/**
Encodes a WKT 3D Polygon [XYZ]
\param out_buf pointer to dynamically growing Text buffer
\param polygon pointer to Point object
\param precision decimal digits to be used for coordinates
\sa gaiaOutPointZ, gaiaOutLinestringZ
\remark mainly intended for internal usage.
*/
GAIAGEO_DECLARE void gaiaOutPolygonZex (gaiaOutBufferPtr out_buf,
gaiaPolygonPtr polygon,
int precision);
/**
Creates a Geometry object from KML notation
\param in_buffer pointer to KML buffer
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaOutBareKml, gaiaOutFullKml
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseKml (const unsigned char
*in_buffer);
/**
Encodes a Geometry object into KML notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\param precision decimal digits to be used for coordinates
\sa gaiaParseKml, gaiaOutFullKml
\note this function will export the simplest KML notation (no descriptions).
*/
GAIAGEO_DECLARE void gaiaOutBareKml (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom, int precision);
/**
Encodes a Geometry object into KML notation
\param out_buf pointer to dynamically growing Text buffer
\param name text string to be set as KML \e name
\param desc text string to se set as KML \e description
\param geom pointer to Geometry object
\param precision decimal digits to be used for coordinates
\sa gaiaParseKml, gaiaOutBareKml
\note this function will export the simplest KML notation (no descriptions).
*/
GAIAGEO_DECLARE void gaiaOutFullKml (gaiaOutBufferPtr out_buf,
const char *name, const char *desc,
gaiaGeomCollPtr geom, int precision);
/**
Creates a Geometry object from GML notation
\param in_buffer pointer to GML buffer
\param sqlite_handle handle to current DB connection
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaParseGml_r, gaiaOutGml
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseGml (const unsigned char
*in_buffer,
sqlite3 * sqlite_handle);
/**
Creates a Geometry object from GML notation
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param in_buffer pointer to GML buffer
\param sqlite_handle handle to current DB connection
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaParseGml, gaiaOutGml
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseGml_r (const void *p_cache,
const unsigned char
*in_buffer,
sqlite3 * sqlite_handle);
/**
Encodes a Geometry object into GML notation
\param out_buf pointer to dynamically growing Text buffer
\param version GML version
\params flippd if TURE the X and Y axes order will be: Y first, X second
\param precision decimal digits to be used for coordinates
\param geom pointer to Geometry object
\sa gaiaParseGml. gaiaOutGml
\note if \e version is set to \b 3, then GMLv3 will be used;
in any other case GMLv2 will be assumed by default.
*/
GAIAGEO_DECLARE void gaiaOutGml_ex (gaiaOutBufferPtr out_buf, int version,
int flipped, int precision,
gaiaGeomCollPtr geom);
/**
Encodes a Geometry object into GML notation
\param out_buf pointer to dynamically growing Text buffer
\param version GML version
\param precision decimal digits to be used for coordinates
\param geom pointer to Geometry object
\sa gaiaParseGml, gaiaOutGml_ex
\note it's simply an alias for gaiaOutGml_ex with FLIPPED set to FALSE.
*/
GAIAGEO_DECLARE void gaiaOutGml (gaiaOutBufferPtr out_buf, int version,
int precision, gaiaGeomCollPtr geom);
/**
Creates a Geometry object from GeoJSON notation
\param in_buffer pointer to GeoJSON buffer
\return the pointer to the newly created Geometry object: NULL on failure
\sa gaiaOutGeoJSON
\note you are responsible to destroy (before or after) any allocated Geometry,
unless you've passed ownership of the Geometry object to some further object:
in this case destroying the higher order object will implicitly destroy any
contained child object.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaParseGeoJSON (const unsigned char
*in_buffer);
/**
Encodes a Geometry object into GeoJSON notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\param precision decimal digits to be used for coordinates
\param options GeoJSON specific options
\sa gaiaParseGeoJSON
\note \e options can assume the following values:
\li 1 = BBOX, no CRS
\li 2 = no BBOX, short form CRS
\li 3 = BBOX, short form CRS
\li 4 = no BBOX, long form CRS
\li 5 = BBOX, long form CRS
\li any other value: no BBOX and no CRS
*/
GAIAGEO_DECLARE void gaiaOutGeoJSON (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom, int precision,
int options);
/**
Encodes a Geometry object into SVG notation
\param out_buf pointer to dynamically growing Text buffer
\param geom pointer to Geometry object
\param relative flag: relative or absolute coordinates
\param precision decimal digits to be used for coordinates
\note if \e relative is set to \b 1, then SVG relative coords will be used:
in any other case SVG absolute coords will be assumed by default.
*/
GAIAGEO_DECLARE void gaiaOutSvg (gaiaOutBufferPtr out_buf,
gaiaGeomCollPtr geom, int relative,
int precision);
/**
Allocates a new DBF Field Value object [duplicating an existing one]
\param org pointer to input DBF Field Value object.
\return the pointer to newly created DBF Field object.
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField, gaiaCloneValue,
gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaValuePtr gaiaCloneValue (gaiaValuePtr org);
/**
Resets a DBF Field Value object to its initial empty state
\param p pointer to DBF Field Value object
\sa gaiaAllocDbfField, gaiaCloneDbfField, gaiaCloneValue,
gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue, gaiaResetDbfEntity
*/
GAIAGEO_DECLARE void gaiaFreeValue (gaiaValuePtr p);
/**
Allocates a new DBF Field object
\param name text string: DBF Field name.
\param type identifier of the corresponding DBF data type.
\param offset corresponding offset into the DBF I/O buffer.
\param length max field length (in bytes).
\param decimals precision: number of decimal digits.
\return the pointer to newly created DBF Field object.
\sa gaiaFreeDbfField, gaiaCloneDbfField, gaiaFreeValue,
gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue
\note you are responsible to destroy (before or after) any allocated DBF Field,
unless you've passed ownership to some further object: in this case destroying the higher order object will implicitly destroy any contained child object.
\n supported DBF data types are:
\li 'C' text string [default]
\li 'N' numeric
\li 'D' date
\li 'L' boolean
*/
GAIAGEO_DECLARE gaiaDbfFieldPtr gaiaAllocDbfField (char *name,
unsigned char type,
int offset,
unsigned char length,
unsigned char decimals);
/**
Destroys a DBF Field object
\param p pointer to DBF Field object
\sa gaiaAllocDbfField, gaiaCloneDbfField, gaiaCloneValue,
gaiaFreeValue, gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue
*/
GAIAGEO_DECLARE void gaiaFreeDbfField (gaiaDbfFieldPtr p);
/**
Allocates a new DBF Field object [duplicating an existing one]
\param org pointer to input DBF Field object.
\return the pointer to newly created DBF Field object.
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField,
gaiaFreeValue, gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue
\note the newly created object is an exact copy of the original one
[this including an evantual Field Value].
*/
GAIAGEO_DECLARE gaiaDbfFieldPtr gaiaCloneDbfField (gaiaDbfFieldPtr org);
/**
Sets a NULL current value for a DBF Field object
\param field pointer to DBF Field object
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField,
gaiaFreeValue, gaiaSetIntValue, gaiaSetDoubleValue,
gaiaSetStrValue
*/
GAIAGEO_DECLARE void gaiaSetNullValue (gaiaDbfFieldPtr field);
/**
Sets an INTEGER current value for a DBF Field object
\param field pointer to DBF Field object.
\param value integer value to be set.
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField,
gaiaFreeValue, gaiaSetNullValue, gaiaSetDoubleValue,
gaiaSetStrValue
*/
GAIAGEO_DECLARE void gaiaSetIntValue (gaiaDbfFieldPtr field,
sqlite3_int64 value);
/**
Sets a DOUBLE current value for a DBF Field object
\param field pointer to DBF Field object.
\param value double value to be set.
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField,
gaiaFreeValue, gaiaSetNullValue, gaiaSetIntValue, gaiaSetStrValue
*/
GAIAGEO_DECLARE void gaiaSetDoubleValue (gaiaDbfFieldPtr field,
double value);
/**
Sets a TEXT current value for a DBF Field object
\param field pointer to DBF Field object.
\param str text string value to be set.
\sa gaiaAllocDbfField, gaiaFreeDbfField, gaiaCloneDbfField,
gaiaFreeValue, gaiaSetNullValue, gaiaSetIntValue, gaiaSetDoubleValue
*/
GAIAGEO_DECLARE void gaiaSetStrValue (gaiaDbfFieldPtr field, char *str);
/**
Creates an initially empty DBF List object
\return the pointer to newly allocated DBF List object: NULL on failure.
\sa gaiaFreeDbfList, gaiaIsValidDbfList,
gaiaResetDbfEntity, gaiaCloneDbfEntity, gaiaAddDbfField
\note you are responsible to destroy (before or after) any allocated DBF List,
unless you've passed ownership to some further object: in this case destroying
the higher order object will implicitly destroy any contained child object.
*/
GAIAGEO_DECLARE gaiaDbfListPtr gaiaAllocDbfList (void);
/**
Destroys a DBF List object
\param list pointer to the DBF List object
\sa gaiaAllocDbfList, gaiaIsValidDbfList,
gaiaResetDbfEntity, gaiaCloneDbfEntity, gaiaAddDbfField
\note attempting to destroy any DBF List object whose ownnership has already
been transferred to some other (higher order) object is a serious error,
and will easily cause severe memory corruption.
*/
GAIAGEO_DECLARE void gaiaFreeDbfList (gaiaDbfListPtr list);
/**
Checks a DBF List object for validity
\param list pointer to the DBF List object.
\return 0 if not valid: any other value if valid.
\sa gaiaAllocDbfList, gaiaFreeDbfList, gaiaIsValidDbfList,
gaiaResetDbfEntity, gaiaCloneDbfEntity, gaiaAddDbfField
*/
GAIAGEO_DECLARE int gaiaIsValidDbfList (gaiaDbfListPtr list);
/**
Inserts a further DBF Field object into a DBF List object
\param list pointer to the DBF List object.
\param name text string: DBF Field name.
\param type identifier of the corresponding DBF data type.
\param offset corresponding offset into the DBF I/O buffer.
\param length max field length (in bytes).
\param decimals precision: number of decimal digits.
\return the pointer to newly created DBF Field object.
\sa gaiaAllocDbfField
\note supported DBF data types are:
\li 'C' text string [default]
\li 'N' numeric
\li 'D' date
\li 'L' boolean
*/
GAIAGEO_DECLARE gaiaDbfFieldPtr gaiaAddDbfField (gaiaDbfListPtr list,
char *name,
unsigned char type,
int offset,
unsigned char length,
unsigned char decimals);
/**
Resets a DBF List object to its initial empty state
\param list pointer to the DBF List object.
\sa gaiaFreeValue
\note any DBF Field associated to the List object will be reset to its
initial empty state (i.e. \e no \e value at all).
*/
GAIAGEO_DECLARE void gaiaResetDbfEntity (gaiaDbfListPtr list);
/**
Allocates a new DBF List object [duplicating an existing one]
\param org pointer to input DBF List object.
\return the pointer to newly created DBF List object.
\sa gaiaCloneDbfField, gaiaCloneValue,
\note the newly created object is an exact copy of the original one.
\n this including any currently set Field Value.
*/
GAIAGEO_DECLARE gaiaDbfListPtr gaiaCloneDbfEntity (gaiaDbfListPtr org);
/**
Allocates a new Shapefile object.
\return the pointer to newly created Shapefile object.
\sa gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note you are responsible to destroy (before or after) any allocated Shapefile.
\n you should phisically open the Shapefile in \e read or \e write mode
before performing any actual I/O operation.
*/
GAIAGEO_DECLARE gaiaShapefilePtr gaiaAllocShapefile (void);
/**
Destroys a Shapefile object
\param shp pointer to the Shapefile object.
\sa gaiaAllocShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note destroying the Shapefile object will close any related file:
anyway you a responsible to explicitly call gaiaFlushShpHeader
before destroyng a Shapefile opened in \e write mode.
*/
GAIAGEO_DECLARE void gaiaFreeShapefile (gaiaShapefilePtr shp);
/**
Open a Shapefile in read mode
\param shp pointer to the Shapefile object.
\param path \e abstract pathname to the corresponding file-system files.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note on failure the object member \e Valid will be set to 0; and the
object member \e LastError will contain the appropriate error message.
\n the \e abstract pathname should not contain any suffix at all.
*/
GAIAGEO_DECLARE void gaiaOpenShpRead (gaiaShapefilePtr shp,
const char *path,
const char *charFrom,
const char *charTo);
/**
Open a Shapefile in write mode - extended
\param shp pointer to the Shapefile object.
\param path \e abstract pathname to the corresponding file-system files.
\param shape the SHAPE code; expected to be one of GAIA_SHP_POINT,
GAIA_SHP_POLYLINE, GAIA_SHP_POLYGON, GAIA_SHP_MULTIPOINT, GAIA_SHP_POINTZ,
GAIA_SHP_POLYLINEZ, GAIA_SHP_POLYGONZ, GAIA_SHP_MULTIPOINTZ,
GAIA_SHP_POINTM, GAIA_SHP_POLYLINEM, GAIA_SHP_POLYGONM, GAIA_SHP_MULTIPOINTM
\param list pointer to DBF List object representing the corresponding
data attributes.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders,
gaiaOpenShpWrite
\note on failure the object member \e Valid will be set to 0; and the
object member \e LastError will contain the appropriate error message.
\n the \e abstract pathname should not contain any suffix at all.
*/
GAIAGEO_DECLARE void gaiaOpenShpWriteEx (gaiaShapefilePtr shp,
const char *path, int shape,
gaiaDbfListPtr list,
const char *charFrom,
const char *charTo,
int colname_case);
/**
Open a Shapefile in write mode
\param shp pointer to the Shapefile object.
\param path \e abstract pathname to the corresponding file-system files.
\param shape the SHAPE code; expected to be one of GAIA_SHP_POINT,
GAIA_SHP_POLYLINE, GAIA_SHP_POLYGON, GAIA_SHP_MULTIPOINT, GAIA_SHP_POINTZ,
GAIA_SHP_POLYLINEZ, GAIA_SHP_POLYGONZ, GAIA_SHP_MULTIPOINTZ,
GAIA_SHP_POINTM, GAIA_SHP_POLYLINEM, GAIA_SHP_POLYGONM, GAIA_SHP_MULTIPOINTM
\param list pointer to DBF List object representing the corresponding
data attributes.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders,
gaiaOpenShpWriteEx
\note simply calls gaiaOpenShpWriteEx() by specifying GAIA_DBF_COLNAME_LOWERCASE
*/
GAIAGEO_DECLARE void gaiaOpenShpWrite (gaiaShapefilePtr shp,
const char *path, int shape,
gaiaDbfListPtr list,
const char *charFrom,
const char *charTo);
/**
Reads a feature from a Shapefile object
\param shp pointer to the Shapefile object.
\param current_row the row number identifying the feature to be read.
\param srid feature's SRID
\return 0 on failure: any other value on success.
-1 when the corresponding DBF record is marked as DELETED.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note on completion the Shapefile's \e Dbf member will contain the feature
read:
\li the \e Dbf->Geometry member will contain the corresponding Geometry
\li and the \e Dbf->First member will point to the linked list containing
the corresponding data attributes [both data formats and values].
\remark the Shapefile object should be opened in \e read mode.
*/
GAIAGEO_DECLARE int gaiaReadShpEntity (gaiaShapefilePtr shp,
int current_row, int srid);
/**
Reads a feature from a Shapefile object
\param shp pointer to the Shapefile object.
\param current_row the row number identifying the feature to be read.
\param srid feature's SRID
\param text_dates is TRUE all DBF dates will be considered as TEXT
\return 0 on failure: any other value on success.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaShpAnalyze, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note on completion the Shapefile's \e Dbf member will contain the feature
read:
\li the \e Dbf->Geometry member will contain the corresponding Geometry
\li and the \e Dbf->First member will point to the linked list containing
the corresponding data attributes [both data formats and values].
\remark the Shapefile object should be opened in \e read mode.
*/
GAIAGEO_DECLARE int gaiaReadShpEntity_ex (gaiaShapefilePtr shp,
int current_row, int srid,
int text_dates);
/**
Prescans a Shapefile object gathering informations
\param shp pointer to the Shapefile object.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaWriteShpEntity, gaiaFlushShpHeaders
\note on completion the Shapefile's \e EffectiveType will containt the
Geometry type corresponding to features actually found.
\remark the Shapefile object should be opened in \e read mode.
*/
GAIAGEO_DECLARE void gaiaShpAnalyze (gaiaShapefilePtr shp);
/**
Writes a feature into a Shapefile object
\param shp pointer to the Shapefile object.
\param entity pointer to DBF List object containing both Geometry and Field
values.
\return 0 on failure: any other value on success.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaFlushShpHeaders
\remark the Shapefile object should be opened in \e write mode.
*/
GAIAGEO_DECLARE int gaiaWriteShpEntity (gaiaShapefilePtr shp,
gaiaDbfListPtr entity);
/**
Writes into an output Shapefile any required header / footer
\param shp pointer to the Shapefile object.
\sa gaiaAllocShapefile, gaiaFreeShapefile, gaiaOpenShpRead, gaiaOpenShpWrite,
gaiaReadShpEntity, gaiaShpAnalyze, gaiaWriteShpEntity
\note forgetting to call gaiaFlushShpHeader for any Shapefile opened in
\e write mode immediately before destroying the object, will surely
cause severe file corruption.
*/
GAIAGEO_DECLARE void gaiaFlushShpHeaders (gaiaShapefilePtr shp);
/**
Allocates a new DBF File object.
\return the pointer to newly created DBF File object.
\sa gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader
\note you are responsible to destroy (before or after) any allocated DBF File.
\n you should phisically open the DBF File in \e read or \e write mode
before performing any actual I/O operation.
*/
GAIAGEO_DECLARE gaiaDbfPtr gaiaAllocDbf (void);
/**
Destroys a DBF File object
\param dbf pointer to the DBF File object.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfWrite,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader
\note destroying the Shapefile object will close any related file:
anyway you a responsible to explicitly call gaiaFlushShpHeader
before destroyng a Shapefile opened in \e write mode.
*/
GAIAGEO_DECLARE void gaiaFreeDbf (gaiaDbfPtr dbf);
/**
Open a DBF File in read mode
\param dbf pointer to the DBF File object.
\param path pathname to the corresponding file-system file.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfWrite, gaiaOpenZipDbf,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader
\note on failure the object member \e Valid will be set to 0; and the
object member \e LastError will contain the appropriate error message.
*/
GAIAGEO_DECLARE void gaiaOpenDbfRead (gaiaDbfPtr dbf,
const char *path,
const char *charFrom,
const char *charTo);
/**
Open a DBF File contained within a Zipfile (just for checking its fields)
\param zip_path path of the Zipfile.
\param filename filename of the DB file within the Zipfile.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\return dbf pointer to the DBF File object. NULL on error.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfWrite,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader
\note you are responsible to destroy (before or after) any allocated DBF File.
\n you should phisically open the DBF File in \e read or \e write mode
before performing any actual I/O operation.
*/
GAIAGEO_DECLARE gaiaDbfPtr gaiaOpenZipDbf (const char *zip_path,
const char *filename,
const char *charFrom,
const char *charTo);
/**
Open a DBF File in write mode,- extended
\param dbf pointer to the DBF File object.
\param path pathname to the corresponding file-system file.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader,
gaiaOpenDbfWrite
\note on failure the object member \e Valid will be set to 0; and the
object member \e LastError will contain the appropriate error message.
*/
GAIAGEO_DECLARE void gaiaOpenDbfWriteEx (gaiaDbfPtr dbf,
const char *path,
const char *charFrom,
const char *charTo,
int colname_case);
/**
Open a DBF File in write mode
\param dbf pointer to the DBF File object.
\param path pathname to the corresponding file-system file.
\param charFrom GNU ICONV name identifying the input charset encoding.
\param charTo GNU ICONV name identifying the output charset encoding.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead,
gaiaReadDbfEntity, gaiaWriteDbfEntity, gaiaFlushDbfHeader,
gaiaOpenDbfWriteEx
\note simply calls gaiaOpenDbfWriteEx() by specifying GAIA_DBF_COLNAME_LOWERCASE
*/
GAIAGEO_DECLARE void gaiaOpenDbfWrite (gaiaDbfPtr dbf,
const char *path,
const char *charFrom,
const char *charTo);
/**
Reads a record from a DBF File object
\param dbf pointer to the DBF File object.
\param current_row the row number identifying the record to be read.
\param deleted on completion this variable will contain 0 if the record
just read is valid: any other value if the record just read is marked as
\e logically \e deleted.
\return 0 on failure: any other value on success.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
gaiaFlushDbfHeader
\note on completion the DBF File \e First member will point to the
linked list containing the corresponding data attributes [both data
formats and values].
\remark the DBF File object should be opened in \e read mode.
*/
GAIAGEO_DECLARE int gaiaReadDbfEntity (gaiaDbfPtr dbf, int current_row,
int *deleted);
/**
Reads a record from a DBF File object
\param dbf pointer to the DBF File object.
\param current_row the row number identifying the record to be read.
\param deleted on completion this variable will contain 0 if the record
\param text_dates is TRUE all DBF dates will be considered as TEXT
just read is valid: any other value if the record just read is marked as
\e logically \e deleted.
\return 0 on failure: any other value on success.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
gaiaFlushDbfHeader
\note on completion the DBF File \e First member will point to the
linked list containing the corresponding data attributes [both data
formats and values].
\remark the DBF File object should be opened in \e read mode.
*/
GAIAGEO_DECLARE int gaiaReadDbfEntity_ex (gaiaDbfPtr dbf, int current_row,
int *deleted, int text_dates);
/**
Writes a record into a DBF File object
\param dbf pointer to the DBF File object.
\param entity pointer to DBF List object containing Fields and corresponding
values.
\return 0 on failure: any other value on success.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
gaiaReadDbfEntity, gaiaFlushDbfHeader
\remark the DBF File object should be opened in \e write mode.
*/
GAIAGEO_DECLARE int gaiaWriteDbfEntity (gaiaDbfPtr dbf,
gaiaDbfListPtr entity);
/**
Writes into an output DBF File any required header / footer
\param dbf pointer to the DBF File object.
\sa gaiaAllocDbf, gaiaFreeDbf, gaiaOpenDbfRead, gaiaOpenDbfWrite,
gaiaReadDbfEntity, gaiaWriteDbfEntity
\note forgetting to call gaiaFlushDbfHeader for any DBF File opened in
\e write mode immediately before destroying the object, will surely
cause severe file corruption.
*/
GAIAGEO_DECLARE void gaiaFlushDbfHeader (gaiaDbfPtr dbf);
/**
Reads from a Memory File
\param ptr pointer to the output buffer.
\param bytes numeber of bytes to read.
\param mem pointer to the Memory File object.
\return the number of bytes read.
\sa gaiaMemFseek
*/
GAIAGEO_DECLARE size_t gaiaMemRead (void *ptr, size_t bytes,
gaiaMemFilePtr mem);
/**
Repositioning a Memory File
\param mem pointer to the Memry File object.
\param offset file offset relative to the start of file
\return 0 on success; -1 on failure.
\sa gaiaFseek
*/
GAIAGEO_DECLARE int gaiaMemFseek (gaiaMemFilePtr mem, off_t offset);
/**
Attempting to get a WKT from the .PRJ member of a given zipped Shapefile
\param zip_path absolute or relativ pathname leading to the Zipfile.
\param basename name of the Shapefile (excluding any .shp, .shx or .dbf suffix)
\return the returned WKT expression from the .prj member of the zipped Shapefile
or NULL on failure
\note the WKT expression corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaReadWktFromZipShp (const char *zip_path,
const char *basename);
/**
Will return the number of Shapefiles from within a given Zipfile
\param zip_path absolute or relativ pathname leading to the Zipfile.
\param count on success will contain the number of Shapefiles
\return 0 on failure; any other value on success.
*/
GAIAGEO_DECLARE int gaiaZipfileNumSHP (const char *zip_path, int *count);
/**
Will return the basename of the Nth Shapefile from within a given Zipfile
\param zip_path absolute or relativ pathname leading to the Zipfile.
\param idx index (1-based) of the Shapefile
\return the basename of the Nth Shapefile
or NULL on failure
\note the returned basename corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaZipfileShpN (const char *zip_path, int idx);
/**
Will return the number of DBF files from within a given Zipfile
\param zip_path absolute or relativ pathname leading to the Zipfile.
\param count on success will contain the number of DBF files
\return 0 on failure; any other value on success.
*/
GAIAGEO_DECLARE int gaiaZipfileNumDBF (const char *zip_path, int *count);
/**
Will return the filename of the Nth DBF file from within a given Zipfile
\param zip_path absolute or relativ pathname leading to the Zipfile.
\param idx index (1-based) of the DBF file
\return the filename of the Nth DBF file
or NULL on failure
\note the returned filename corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaZipfileDbfN (const char *zip_path, int idx);
#ifndef OMIT_ICONV /* ICONV enabled: supporting text reader */
/**
Creates a Text Reader object
\param path to the corresponding file-system file.
\param field_separator the character acting as a separator between adjacent
fields.
\param text_separator the character used to quote text strings.
\param decimal_separator the character used as a separator between integer
and decimal digits for real numeric values.
\param first_line_titles 0 if the first line contains regular values:
any other value if the first line contains column names.
\param encoding GNU ICONV name identifying the input charset encoding.
\return the pointer to the newly created Text Reader object: NULL on failure
\sa gaiaTextReaderDestroy, gaiaTextReaderParse,
gaiaTextReaderGetRow, gaiaTextReaderFetchField
\note you are responsible to destroy (before or after) any allocated Text
Reader object.
*/
GAIAGEO_DECLARE gaiaTextReaderPtr gaiaTextReaderAlloc (const char *path,
char
field_separator,
char
text_separator,
char
decimal_separator,
int
first_line_titles,
const char
*encoding);
/**
Destroys a Text Reader object
\param reader pointer to Text Reader object.
\sa gaiaTextReaderAlloc, gaiaTextReaderParse,
gaiaTextReaderGetRow, gaiaTextReaderFetchField
*/
GAIAGEO_DECLARE void gaiaTextReaderDestroy (gaiaTextReaderPtr reader);
/**
Prescans the external file associated to a Text Reade object
\param reader pointer to Text Reader object.
\return 0 on failure: any other value on success.
\sa gaiaTextReaderAlloc, gaiaTextReaderDestroy,
gaiaTextReaderGetRow, gaiaTextReaderFetchField
\note this preliminary step is required so to ensure:
\li file consistency: checking expected formatting rules.
\li identifying the number / type / name of fields [aka columns].
\li identifying the actual number of lines within the file.
*/
GAIAGEO_DECLARE int gaiaTextReaderParse (gaiaTextReaderPtr reader);
/**
Reads a line from a Text Reader object
\param reader pointer to Text Reader object.
\param row_num the Line Number identifying the Line to be read.
\return 0 on failure: any other value on success.
\sa gaiaTextReaderAlloc, gaiaTextReaderDestroy, gaiaTextReaderParse,
gaiaTextReaderFetchField
\note this function will load the requested Line into the current buffer:
you can then use gaiaTextReaderFetchField in order to retrieve
any individual field [aka column] value.
*/
GAIAGEO_DECLARE int gaiaTextReaderGetRow (gaiaTextReaderPtr reader,
int row_num);
/**
Retrieves an individual field value from the current Line
\param reader pointer to Text Reader object.
\param field_num relative field [aka column] index: first field has index 0.
\param type on completion this variable will contain the value type.
\param value on completion this variable will contain the current field value.
\return 0 on failure: any other value on success.
\sa gaiaTextReaderAlloc, gaiaTextReaderDestroy, gaiaTextReaderParse,
gaiaTextReaderGetRow
*/
GAIAGEO_DECLARE int gaiaTextReaderFetchField (gaiaTextReaderPtr reader,
int field_num, int *type,
const char **value);
#endif /* end ICONV (text reader) */
#ifdef __cplusplus
}
#endif
#endif /* _GG_FORMATS_H */
libspatialite-5.1.0/src/headers/spatialite/gg_dynamic.h 0000644 0001750 0001750 00000031400 14463127014 020077 0000000 0000000 /*
gg_dynamic.h -- Gaia common support for geometries: DynamicLine functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_dynamic.h
Geometry handling functions: DynamicLine handling
*/
#ifndef _GG_DYNAMIC
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_DYNAMIC
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* function prototypes */
/**
Creates a new dynamicly growing line/ring object
\return the pointer to newly created object
\sa gaiaCreateDynamicLine, gaiaFreeDynamicLine
\note you are responsible to destroy (before or after) any allocated
dynamically growing line/ring object.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr gaiaAllocDynamicLine (void);
/**
Destroys a dynamically growing line/ring object
\param p pointer to object to be destroyed
\sa gaiaAllocDynamicLine
*/
GAIAGEO_DECLARE void gaiaFreeDynamicLine (gaiaDynamicLinePtr p);
/**
Appends a new 2D Point [XY] at the end of a dynamically growing line/ring
object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointToDynamicLine (gaiaDynamicLinePtr p, double x, double y);
/**
Appends a new 3D Point [XYZ] at the end of a dynamically growing line/ring
object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param z Z coordinate of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointZToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double z);
/**
Appends a new 2D Point [XYM] at the end of a dynamically growing line/ring
object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param m M measure of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointMToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double m);
/**
Appends a new 3D Point [XYZM] at the end of a dynamically growing line/ring
object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param z Z coordinate of the Point
\param m M measure of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointZMToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double z, double m);
/**
Appends a new 2D Point [XY] before the first one of a dynamically growing
line/ring object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointToDynamicLine (gaiaDynamicLinePtr p, double x,
double y);
/**
Appends a new 3D Point [XYZ] before the first one of a dynamically growing
line/ring object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param z Z coordinate of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointZToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double z);
/**
Appends a new 2D Point [XYM] before the first one of a dynamically growing
line/ring object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param m M measure of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointMToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double m);
/**
Appends a new 3D Point [XYZM] before the first one of a dynamically growing
line/ring object
\param p pointer to the dynamically growing line/ring object.
\param x X coordinate of the Point
\param y Y coordinate of the Point
\param z Z coordinate of the Point
\param m M measure of the Point
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointZMToDynamicLine (gaiaDynamicLinePtr p, double x,
double y, double z, double m);
/**
Appends a new 2D Point [XY] immediately after the given Point into a
dynamically growing line/ring object
\param p pointer to the dynamically growing line/ring object.
\param pt pointer to the given Point.
\param x X coordinate of the Point to be appended
\param y Y coordinate of the Point to be appended
\sa gaiaDynamicLiceInsertBefore
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineInsertAfter (gaiaDynamicLinePtr p, gaiaPointPtr pt,
double x, double y);
/**
Appends a new 2D Point [XY] immediately before the given Point into a
dynamically growing line/ring object
\param p pointer to the dynamically growing line/ring object.
\param pt pointer to the given Point.
\param x X coordinate of the Point to be appended
\param y Y coordinate of the Point to be appended
\sa gaiaDynamicLiceInsertBeforeAfter
\return the pointer to newly created Point
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineInsertBefore (gaiaDynamicLinePtr p, gaiaPointPtr pt,
double x, double y);
/**
Removes a given Point from a dynamically growing line/ring object
\param p pointer to dynamically growing line/ring object.
\param pt pointer to given Point.
\note the given Point (referenced by its address) will be removed from
the dynamically growin line/ring object.
\n the given Point will be then implicitly destroyed.
*/
GAIAGEO_DECLARE void gaiaDynamicLineDeletePoint (gaiaDynamicLinePtr p,
gaiaPointPtr pt);
/**
Duplicates a dynamically growing line/ring object
\param org pointer to dynamically growing line/ring object [origin].
\return the pointer to newly created dynamic growing line/ring object:
NULL on failure.
\note the newly created object is an exact copy of the original one.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaCloneDynamicLine (gaiaDynamicLinePtr org);
/**
Duplicates and reverts a dynamically growing line/ring object
\param org pointer to dynamically growing line/ring object [origin].
\return the pointer to newly created dynamic growing line/ring object:
NULL on failure.
\note the newly created object is an exact copy of the origina one, except
in that direction is reverted.
\n i.e. first inpunt point becomes last output point, and last input point
becomes first output point.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaReverseDynamicLine (gaiaDynamicLinePtr org);
/**
Cuts a dynamically growing line/ring in two halves, using a given
cut point
\param org pointer to the input object [the line to be split].
\param point pointer to given cut point.
\return the pointer to newly created dynamic growing line/ring object:
NULL on failure.
\sa gaiaDynamicLineSplitAfter
\note the newly created object will contain a line going from the orginal
first point to the cut point [excluded].
\n on completion the orginal line will be reduced, going from the cut
point [included] to the original last point.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineSplitBefore (gaiaDynamicLinePtr org, gaiaPointPtr point);
/**
Cuts a dynamically growing line/ring in two halves, using a given
cut point
\param org pointer to the input object [the line to be split].
\param point pointer to given cut point.
\return the pointer to newly created dynamic growing line/ring object:
NULL on failure.
\sa gaiaDynamicLineSplitBefore
\note the newly created object will contain a line going from the orginal
first point to the cut point [included].
\n on completion the orginal line will be reduced, going from the cut
point [excluded] to the original last point.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineSplitAfter (gaiaDynamicLinePtr org, gaiaPointPtr point);
/**
Merges two dynamically growing line/ring object into a single one
\param org pointer to the first input object [first line].
\param point pointer to the reference Point object.
\param toJoin pointer to the second input object [second line].
\return the pointer to newly created dynamically growing line/ring object
[merged line]: NULL on failure.
\sa gaiaDynamicLineJoinBefore
\note the reference Point must exists into the first line: the second line
will then be inserted immediately after the reference Point.
\n The newly created object will represent the resulting merged line:
\n both input objects remain untouched.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineJoinAfter (gaiaDynamicLinePtr org, gaiaPointPtr point,
gaiaDynamicLinePtr toJoin);
/**
Merges two dynamically growing line/ring object into a single one
\param org pointer to the first input object [first line].
\param point pointer to the reference Point object.
\param toJoin pointer to the second input object [second line].
\return the pointer to newly created dynamically growing line/ring object
[merged line]: NULL on failure.
\sa gaiaDynamicLineJoinAfter
\note the reference Point must exists into the first line: the second line
will then be inserted immediately before the reference Point.
\n The newly created object will represent the resulting merged line:
\n both input objects remain untouched.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineJoinBefore (gaiaDynamicLinePtr org, gaiaPointPtr point,
gaiaDynamicLinePtr toJoin);
/**
Finds a Point within a dymically growing line/ring object [by coords]
\param p pointer to dymamically line/ring object.
\param x Point X coordinate.
\param y Point Y coordinate.
\return the pointer to the corresponding Point object: NULL on failure.
\sa gaiaDynamicLineFindByPos
\note if the line object contains more Points sharing the same coordinates,
a reference to the first one found will be returned.
*/
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineFindByCoords (gaiaDynamicLinePtr p, double x, double y);
/**
Finds a Point within a dymically growing line/ring object [by position]
\param p pointer to dymamically line/ring object.
\param pos relative position [first Point has index 0].
\return the pointer to the corresponding Point object: NULL on failure.
\sa gaiaDynamicLineFindByCoords
*/
GAIAGEO_DECLARE gaiaPointPtr gaiaDynamicLineFindByPos (gaiaDynamicLinePtr
p, int pos);
/**
Creates a new dynamicly growing line/ring object
\param coords an array of COORDs, any dimension [XY, XYZ, XYM, XYZM]
\param points number of points [aka vertices] into the array
\return the pointer to newly created object
\sa gaiaAllocDynamicLine, gaiaFreeDynamicLine, gaiaLinestringStruct,
gaiaRingStruct
\note you are responsible to destroy (before or after) any allocated
dynamically growing line/ring object.
\n The COORDs array is usually expected to be one found within a
gaiaLinestring or gaiaRing object.
*/
GAIAGEO_DECLARE gaiaDynamicLinePtr gaiaCreateDynamicLine (double *coords,
int points);
#ifdef __cplusplus
}
#endif
#endif /* _GG_DYNAMIC */
libspatialite-5.1.0/src/headers/spatialite/gg_advanced.h 0000644 0001750 0001750 00000514177 14463127014 020241 0000000 0000000 /*
gg_advanced.h -- Gaia common support for geometries: advanced
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/*
CREDITS:
this module has been partly funded by:
Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
(wrapping liblwgeom APIs)
*/
/**
\file gg_advanced.h
Geometry handling functions: advanced
*/
#ifndef _GG_ADVANCED_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_ADVANCED_H
#endif
/** Gaia-to-GEOS: all geometries */
#define GAIA2GEOS_ALL 0
/** Gaia-to-GEOS: only geometries of the Point type */
#define GAIA2GEOS_ONLY_POINTS 1
/** Gaia-to-GEOS: only geometries of the Linestring type */
#define GAIA2GEOS_ONLY_LINESTRINGS 2
/** Gaia-to-GEOS: only geometries of the Polygon type */
#define GAIA2GEOS_ONLY_POLYGONS 3
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
#include
#else
#include
#endif
#ifndef OMIT_PROJ /* including PROJ */
/**
Resets the PROJ error messages to an empty state
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\sa gaiaSetProjErrorMsg_r, gaiaGetProjErrorMsg_r
\note reentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE void gaiaResetProjErrorMsg_r (const void *p_cache);
/**
Set the current PROJ error message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the error message to be set.
\sa gaiaResetProjErrorMsg_r, gaiaGetProjErrorMsg_r
\note reentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE void gaiaSetProjErrorMsg_r (const void *p_cache,
const char *msg);
/**
Return the latest PROJ error message (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the latest PROJ error message: an empty string if no error was
previoysly found.
\sa gaiaSetProjErrorMsg_r, gaiaResetProjErrorMsg_r
\note reentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE const char *gaiaGetProjErrorMsg_r (const void *p_cache);
/**
Sets the PATH leading to the private PROJ.6 database
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param path the pathname to be set
\return the currently set PATH leading to the private PROJ.6 database;
NULL if no PROJ database is defined.
\sa gaiaGetProjDatabasePath
\note reentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE const char *gaiaSetProjDatabasePath (const void *p_cache,
const char *path);
/**
Return the currently set PATH leading to the private PROJ.6 database
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the currently set PATH leading to the private PROJ.6 database;
NULL if no PROJ database is defined.
\sa gaiaSetProjDatabasePath
\note reentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE const char *gaiaGetProjDatabasePath (const void *p_cache);
/**
Return the proj-string corresponding to a given CRS defined within
the private PROJ.6 database
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param auth_name if NULL will be interpreted as "EPSG"
\param auth_srid the intended CRS is identified by auth_name and auth_srid
\return the proj-string expression corresponding to the given CRS
NULL on failite.
\note you are responsible to destroy (before or after) any proj-string
returned by gaiaGetProjString()
\nreentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE char *gaiaGetProjString (const void *p_cache,
const char *auth_name,
int auth_srid);
/**
Return the WKT expression corresponding to a given CRS defined within
the private PROJ.6 database
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param auth_name if NULL will be interpreted as "EPSG"
\param auth_srid the intended CRS is identified by auth_name and auth_srid
\param style one between GAIA_PROJ_WKT_GDAL, GAIA_PROJ_WKT_ESRI,
GAIA_PROJ_WKT_ISO_2015 or GAIA_PROJ_WKT_ISO_2018 (this latter being the
default assumption).
\param indented if TRUE the WKT expression will be properly indented,
otherwise a solid string lacking any white space or new-line will be
printed.
\param indentation how many chars to be used for indenting (only
considered if indented is TRUE).
\return the WKT expression corresponding to the given CRS
NULL on failite.
\note you are responsible to destroy (before or after) any WKT string
returned by gaiaGetProjWKT()
\nreentrant and thread-safe.
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE char *gaiaGetProjWKT (const void *p_cache,
const char *auth_name,
int auth_srid, int style,
int indented, int indentation);
/**
Return the SRID corresponding to a given WKT expression (if any)
\param db_handle pointer to the current DB connection.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param wkt the WKT expression to be evaluated.
\param srid on successful completion will point to the SRID value
matching the WKT expression.
\return 0 on failure: any other value on success
\remark \b PROJ.6 support required.
*/
GAIAGEO_DECLARE int gaiaGuessSridFromWKT (sqlite3 * db_handle,
const void *p_cache,
const char *wkt, int *srid);
/**
Converts and angle from Radians into Degrees
\param rads the angle measured in Radians.
\return the angle measured in Degrees.
\sa gaiaDegsToRads
\remark \b PROJ support required
*/
GAIAGEO_DECLARE double gaiaRadsToDegs (double rads);
/**
Converts and angle from Degrees into Radians
\param degs the angle measured in Degrees.
\return the angle measured in Radians.
\sa gaiaRadsToDegs
\remark \b PROJ support required
*/
GAIAGEO_DECLARE double gaiaDegsToRads (double degs);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [PROJ.4 format] qualifying the
input Reference System
\param proj_to geodetic parameters string [PROJ.4 format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransform_r, gaiaTransformXY, gaiaTransformXYZ, gaiaTransformEx,
gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryTransform()\n
not reentrant and thread unsafe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransform (gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [PROJ.4 format] qualifying the
input Reference System
\param proj_to geodetic parameters string [PROJ.4 format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransform, gaiaTransformXY_r, gaiaTransformXYZ_r,
gaiaTransformEx_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryTransform()\n
reentrant and thread-safe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransform_r (const void *p_cache,
gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
\param org pointer to input Geometry object.
\param proj_string_1 any valid string accepted by PROJ.6 for identifying
the origin CRS of a trasformation, or a string defining a trasformation
pipelin.\n
can never be NULL.
\param proj_string_2 any valid string accepted by PROJ.6 for identifying
the destination CRS of a trasformation.\n
expected to be NULL if proj_string_1 defines a pipeline.
\param proj_bbox pointer to aa BoundingBox object defining the
specific "area of use" of the transformation.\n
may be NULL.
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransform, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryTransformEx()\n
not reentrant and thread unsafe.
\remark \b PROJ.6 support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformEx (gaiaGeomCollPtr org,
const char *proj_string_1,
const char *proj_string_2,
gaiaProjAreaPtr proj_bbox);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param org pointer to input Geometry object.
\param proj_string_1 any valid string accepted by PROJ.6 for identifying
the origin CRS of a trasformation, or a string defining a trasformation
pipelin.\n
can never be NULL.
\param proj_string_2 any valid string accepted by PROJ.6 for identifying
the destination CRS of a trasformation.\n
expected to be NULL if proj_string_1 defines a pipeline.
\param proj_bbox pointer to aa BoundingBox object defining the
specific "area of use" of the transformation.\n
may be NULL.
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransform_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryTransformEx()\n
reentrant and thread-safe.
\remark \b PROJ.6 support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformEx_r (const void *p_cache,
gaiaGeomCollPtr org,
const char
*proj_string_1,
const char
*proj_string_2,
gaiaProjAreaPtr
proj_bbox);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
This is a special "flavor" of gaiaTransform() just considering X and Y coordinates;
Z and M values will be left untouched.
Mainly intended as a workaround possibily useful when facing partially
broken PROJ definitions.
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [EPSG format] qualifying the
input Reference System
\param proj_to geodetic parameters string [EPSG format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransformXY_r, gaiaTransformXYZ_r, gaiaTransform, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry, this including any Geometry returned by gaiaGeometryTransform()\n
not reentrant and thread unsafe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformXY (gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
This is a special "flavor" of gaiaTransform_r() just considering X and Y coordinates;
Z and M values will be left untouched.
Mainly intended as a workaround possibily useful when facing partially
broken PROJ definitions.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [EPSG format] qualifying the
input Reference System
\param proj_to geodetic parameters string [EPSG format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransformXY, gaiaTransformXYZ, gaiaTransform_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry, this including any Geometry returned by gaiaGeometryTransform()\n
reentrant and thread-safe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformXY_r (const void *p_cache,
gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
This is a special "flavor" of gaiaTransform() just considering X, Y
and Z coordinates; M values will be left untouched.
Mainly intended as a workaround possibily useful
when handling 4D geometries having M-values not
corresponding to Time.
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [EPSG format] qualifying the
input Reference System
\param proj_to geodetic parameters string [EPSG format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransformXY_r, gaiaTransformXYZ_r, gaiaTransform, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry, this including any Geometry returned by gaiaGeometryTransform()\n
not reentrant and thread unsafe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformXYZ (gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
/**
Tansforms a Geometry object into a different Reference System
[aka Reprojection]
This is a special "flavor" of gaiaTransform() just considering X, Y
and Z coordinates; M values will be left untouched.
Mainly intended as a workaround possibily useful
when handling 4D geometries having M-values not
corresponding to Time.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param org pointer to input Geometry object.
\param proj_from geodetic parameters string [EPSG format] qualifying the
input Reference System
\param proj_to geodetic parameters string [EPSG format] qualifying the
output Reference System
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaTransformXY, gaiaTransformXYZ, gaiaTransform_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry, this including any Geometry returned by gaiaGeometryTransform()\n
reentrant and thread-safe.
\remark \b PROJ support required
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTransformXYZ_r (const void *p_cache,
gaiaGeomCollPtr org,
const char *proj_from,
const char *proj_to);
#endif /* end including PROJ */
#ifndef OMIT_GEOS /* including GEOS */
/**
Resets the GEOS error and warning messages to an empty state
\sa gaiaResetGeosMsg_r,
gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg, gaiaGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaResetGeosMsg (void);
/**
Resets the GEOS error and warning messages to an empty state
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\sa gaiaResetGeosMsg,
gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg, gaiaGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaResetGeosMsg_r (const void *p_cache);
/**
Return the latest GEOS error message (if any)
\return the latest GEOS error message: an empty string if no error was
previoysly found.
\sa gaiaGetGeosErrorMsg_r,
gaiaResetGeosMsg, gaiaGetGeosWarningMsg, gaiaGetGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg,
gaiaCriticalPointFromGEOSmsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosErrorMsg (void);
/**
Return the latest GEOS error message (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the latest GEOS error message: an empty string if no error was
previoysly found.
\sa gaiaGetGeosErrorMsg,
gaiaResetGeosMsg, gaiaGetGeosWarningMsg, gaiaGetGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg,
gaiaCriticalPointFromGEOSmsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosErrorMsg_r (const void *p_cache);
/**
Return the latest GEOS warning message (if any)
\return the latest GEOS warning message: an empty string if no warning was
previoysly found.
\sa gaiaGetGeosWarningMsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg,
gaiaCriticalPointFromGEOSmsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosWarningMsg (void);
/**
Return the latest GEOS warning message (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the latest GEOS warning message: an empty string if no warning was
previoysly found.
\sa gaiaGetGeosWarningMsg,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosAuxErrorMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg,
gaiaCriticalPointFromGEOSmsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosWarningMsg_r (const void *p_cache);
/**
Return the latest GEOS (auxiliary) error message (if any)
\return the latest GEOS (auxiliary) error message: an empty string if no
error was previoysly found.
\sa gaiaGetGeosAuxErrorMsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosAuxErrorMsg (void);
/**
Return the latest GEOS (auxiliary) error message (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the latest GEOS (auxiliary) error message: an empty string if no
error was previoysly found.
\sa gaiaGetGeosAuxErrorMsg,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE const char *gaiaGetGeosAuxErrorMsg_r (const void *p_cache);
/**
Attempts to (possibile) return a Point Geometry extracted from the latest
GEOS error / warning message
\return a Point Geometry: NULL if no warning/error was previoysly found
or if the current GEOS message doesn't contains a critical Point.
\sa gaiaCriticalPointFromGEOSmsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCriticalPointFromGEOSmsg (void);
/**
Attempts to (possibile) return a Point Geometry extracted from the latest
GEOS error / warning message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return a Point Geometry: NULL if no warning/error was previoysly found
or if the current GEOS message doesn't contains a critical Point.
\sa gaiaCriticalPointFromGEOSmsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaSetGeosErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCriticalPointFromGEOSmsg_r (const void
*p_cache);
/**
Set the current GEOS error message
\param msg the error message to be set.
\sa gaiaSetGeosErrorMsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosErrorMsg (const char *msg);
/**
Set the current GEOS error message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the error message to be set.
\sa gaiaSetGeosErrorMsg,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosAuxErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosErrorMsg_r (const void *p_cache,
const char *msg);
/**
Set the current GEOS warning message
\param msg the warning message to be set.
\sa gaiaSetGeosWarningMsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosErrorMsg, gaiaSetGeosAuxErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosWarningMsg (const char *msg);
/**
Set the current GEOS warning message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the warning message to be set.
\sa gaiaSetGeosWarningMsg,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosErrorMsg, gaiaSetGeosAuxErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosWarningMsg_r (const void *p_cache,
const char *msg);
/**
Set the current GEOS (auxiliary) error message
\param msg the error message to be set.
\sa gaiaSetAuxErrorMsg_r,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosErrorMsg
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosAuxErrorMsg (const char *msg);
/**
Set the current GEOS (auxiliary) error message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the error message to be set.
\sa gaiaSetAuxErrorMsg,
gaiaResetGeosMsg, gaiaGetGeosErrorMsg, gaiaGetGeosWarningMsg,
gaiaGetGeosAuxErrorMsg, gaiaSetGeosWarningMsg, gaiaSetGeosErrorMsg
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void gaiaSetGeosAuxErrorMsg_r (const void *p_cache,
const char *msg);
/**
Converts a Geometry object into a GEOS Geometry
\param gaia pointer to Geometry object
\return handle to GEOS Geometry
\sa gaiaToGeos_r, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYM,
gaiaFromGeos_XYZM, gaiaToGeosSelective
\note convenience method, simply defaulting to gaiaToGeosSelective(geom, GAIA2GEOS_ALL)\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void *gaiaToGeos (const gaiaGeomCollPtr gaia);
/**
Converts a Geometry object into a GEOS Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param gaia pointer to Geometry object
\return handle to GEOS Geometry
\sa gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYM,
gaiaFromGeos_XYZM, gaiaToGeosSelective_r
\note convenience method, simply defaulting to gaiaToGeosSelective_r(p_cache, geom, GAIA2GEOS_ALL)\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void *gaiaToGeos_r (const void *p_cache,
const gaiaGeomCollPtr gaia);
/**
Converts a Geometry object into a GEOS Geometry
\param gaia pointer to Geometry object
\param mode one of GAIA2GEOS_ALL, GAIA2GEOS_ONLY_POINTS,
GAIA2GEOS_ONLY_LINESTRINGS or GAIA2GEOS_ONLY_POLYGONS
\return handle to GEOS Geometry
\sa gaiaToGeosSelective_r, gaiaFromGeos_XY, gaiaFromGeos_XYZ,
gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note if the mode argument is not GAIA2GEOS_ALL only elementary geometries
of the selected type will be passed to GEOS, ignoring any other.\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void *gaiaToGeosSelective (const gaiaGeomCollPtr gaia,
int mode);
/**
Converts a Geometry object into a GEOS Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param gaia pointer to Geometry object
\param mode one of GAIA2GEOS_ALL, GAIA2GEOS_ONLY_POINTS,
GAIA2GEOS_ONLY_LINESTRINGS or GAIA2GEOS_ONLY_POLYGONS
\return handle to GEOS Geometry
\sa gaiaToGeosSelective, gaiaFromGeos_XY, gaiaFromGeos_XYZ,
gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note if the mode argument is not GAIA2GEOS_ALL only elementary geometries
of the selected type will be passed to GEOS, ignoring any other.\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE void *gaiaToGeosSelective_r (const void *p_cache,
const gaiaGeomCollPtr gaia,
int mode);
/**
Converts a GEOS Geometry into a Geometry object [XY dims]
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XY_r,
gaiaToGeos, gaiaFromGeos_XYZ, gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XY()\n
not reentrant and thread usafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XY (const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XY dims]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XY,
gaiaToGeos, gaiaFromGeos_XYZ, gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XY_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XY_r (const void *p_cache,
const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYZ dims]
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYZ_r,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYZ()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYZ (const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYZ dims]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYZ,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYM, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYZ_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYZ_r (const void *p_cache,
const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYM dims]
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYM_r,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYM()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYM (const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYM dims]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYM,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYZM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYM_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYM_r (const void *p_cache,
const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYZM dims]
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYZM_r,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYZM()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYZM (const void *geos);
/**
Converts a GEOS Geometry into a Geometry object [XYZM dims]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geos handle to GEOS Geometry
\return the pointer to the newly created Geometry object
\sa gaiaFromGeos_XYZM,
gaiaToGeos, gaiaFromGeos_XY, gaiaFromGeos_XYZ, gaiaFromGeos_XYM
\note you are responsible to destroy (before or after) any allocated
Geometry, this including any Geometry returned by gaiaFromGeos_XYZM_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromGeos_XYZM_r (const void *p_cache,
const void *geos);
/**
Checks if a Geometry object represents an OGC Simple Geometry
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsSimple_r,
gaiaIsClosed, gaiaIsRing, gaiaIsValid
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsSimple (gaiaGeomCollPtr geom);
/**
Checks if a Geometry object represents an OGC Simple Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsSimple,
gaiaIsClosed, gaiaIsRing, gaiaIsValid
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsSimple_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Checks if a Linestring object represents an OGC Closed Geometry
This function only works on a single linestring - if you pass in a multi-line
linestring geometry, it will return 0 (false). See gaiaIsClosedGeom for an
alternative.
\param line pointer to Linestring object.
\return 0 if false; any other value if true
\sa gaiaIsSimple, gaiaIsRing, gaiaIsValid, gaiaIsClosedGeom
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsClosed (gaiaLinestringPtr line);
/**
Checks if a Geometry object represents an OGC Closed Linestring
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsClosedGeom_r,
gaiaIsSimple, gaiaIsRing, gaiaIsValid, gaiaIsClosed
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsClosedGeom (gaiaGeomCollPtr geom);
/**
Checks if a Geometry object represents an OGC Closed Linestring
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsClosedGeom,
gaiaIsSimple, gaiaIsRing, gaiaIsValid, gaiaIsClosed
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsClosedGeom_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Checks if a Linestring object represents an OGC Ring Geometry
\param line pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsRing_r,
gaiaIsSimple, gaiaIsClosed, gaiaIsValid
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsRing (gaiaLinestringPtr line);
/**
Checks if a Linestring object represents an OGC Ring Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param line pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsRing,
gaiaIsSimple, gaiaIsClosed, gaiaIsValid
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsRing_r (const void *p_cache,
gaiaLinestringPtr line);
/**
Checks if a Geometry object represents an OGC Valid Geometry
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsValid_r,
gaiaIsSimple, gaiaIsClosed, gaiaIsRing, gaiaIsValidReason
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsValid (gaiaGeomCollPtr geom);
/**
return a TEXT string stating if a Geometry is valid and if not
valid, a reason why
*
\param geom pointer to the Geometry object to be validated.
\return a text string.
\sa gaiaIsValid, gaiaIsValidReason_r, gaiaIsValidDetail
\note you are responsible to free() the returned text string\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE char *gaiaIsValidReason (gaiaGeomCollPtr geom);
/**
return a TEXT string stating if a Geometry is valid and if not
valid, a reason why
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to the Geometry object to be validated.
\return a text string.
\sa gaiaIsValid_r, gaiaIsValidReason, gaiaIsValidDetail_r
\note you are responsible to free() the returned text string\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE char *gaiaIsValidReason_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
return a Geometry detail causing a Geometry to be invalid
*
\param geom pointer to the Geometry object to be validated.
\return pointer to a Geometry object causing invalidity, or NULL.
\sa gaiaIsValid, gaiaIsValidReason, gaiaIsValidDetail_r
\note you are responsible to destroy the returned Geometry\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaIsValidDetail (gaiaGeomCollPtr geom);
/**
return a Geometry detail causing a Geometry to be invalid
*
\param geom pointer to the Geometry object to be validated.
\param esri_flag if set to TRUE if set to TRUE all ESRI-like holes (violating
the basic OGC model) will be considered to be valid.
\return pointer to a Geometry object causing invalidity, or NULL.
\sa gaiaIsValid, gaiaIsValidReason, gaiaIsValidDetail_r
\note you are responsible to destroy the returned Geometry\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaIsValidDetailEx (gaiaGeomCollPtr geom,
int esri_flag);
/**
return a Geometry detail causing a Geometry to be invalid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to the Geometry object to be validated.
\return pointer to a Geometry object causing invalidity, or NULL.
\sa gaiaIsValid_r, gaiaIsValidReason_r, gaiaIsValidDetail
\note you are responsible to destroy the returned Geometry\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaIsValidDetail_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
return a Geometry detail causing a Geometry to be invalid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to the Geometry object to be validated.
\param esri_flag if set to TRUE all ESRI-like holes (violating
the basic OGC model) will be considered to be valid.
\return pointer to a Geometry object causing invalidity, or NULL.
\sa gaiaIsValid_r, gaiaIsValidReason_r, gaiaIsValidDetail
\note you are responsible to destroy the returned Geometry\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaIsValidDetailEx_r (const void
*p_cache,
gaiaGeomCollPtr
geom, int esri_flag);
/**
Checks if a Geometry object represents an OGC Valid Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object.
\return 0 if false; any other value if true
\sa gaiaIsValid,
gaiaIsSimple, gaiaIsClosed, gaiaIsRing, gaiaIsValidReason_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIsValid_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Measures the total Length for a Geometry object
\param geom pointer to Geometry object
\param length on completion this variable will contain the measured length
\return 0 on failure: any other value on success
\sa gaiaGeomCollLenght_r,
gaiaGeomCollArea, gaiaMeasureLength, gaiaGeomCollLengthOrPerimeter
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollLength (gaiaGeomCollPtr geom,
double *length);
/**
Measures the total Length for a Geometry object
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\param length on completion this variable will contain the measured length
\return 0 on failure: any other value on success
\sa gaiaGeomCollLenght,
gaiaGeomCollArea, gaiaMeasureLength, gaiaGeomCollLengthOrPerimeter
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollLength_r (const void *p_cache,
gaiaGeomCollPtr geom,
double *length);
/**
Measures the total Length or Perimeter for a Geometry object
\param geom pointer to Geometry object
\param perimeter if TRUE only Polygons will be considered, ignoring any Linesting
\n the opposite if FALSE (considering only Linestrings and ignoring any Polygon)
\param length on completion this variable will contain the measured length
or perimeter
\return 0 on failure: any other value on success
\sa gaiaGeomCollLengthOrPerimeter_r,
gaiaGeomCollArea, gaiaMeasureLength, gaiaGeomCollLength
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollLengthOrPerimeter (gaiaGeomCollPtr geom,
int perimeter,
double *length);
/**
Measures the total Length or Perimeter for a Geometry object
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\param perimeter if TRUE only Polygons will be considered, ignoring any Linesting
\n the opposite if FALSE (considering only Linestrings and ignoring any Polygon)
\param length on completion this variable will contain the measured length
or perimeter
\return 0 on failure: any other value on success
\sa gaiaGeomCollLengthOrPerimeter,
gaiaGeomCollArea, gaiaMeasureLength, gaiaGeomCollLength
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollLengthOrPerimeter_r (const void *p_cache,
gaiaGeomCollPtr geom,
int perimeter,
double *length);
/**
Measures the total Area for a Geometry object
\param geom pointer to Geometry object
\param area on completion this variable will contain the measured area
\return 0 on failure: any other value on success
\sa gaiaGeoCollArea_r,
gaiaGeomCollLength, gaiaMeasureArea, gaiaGeodesicArea
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollArea (gaiaGeomCollPtr geom, double *area);
/**
Measures the total Area for a Geometry object
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\param area on completion this variable will contain the measured area
\return 0 on failure: any other value on success
\sa gaiaGeoCollArea,
gaiaGeomCollLength, gaiaMeasureArea, gaiaGeodesicArea
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollArea_r (const void *p_cache,
gaiaGeomCollPtr geom, double *area);
/**
Attempts to rearrange a generic Geometry object into a Polygon or MultiPolygon
\param geom the input Geometry object
\param force_multi if not set to 0, then an eventual Polygon will be
returned casted to MultiPolygon
\return the pointer to newly created Geometry object representing a
Polygon or MultiPolygon Geometry: NULL on failure.
\sa gaiaPolygonize_r, gaiaMakePolygon, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaPolygonize()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaPolygonize (gaiaGeomCollPtr geom,
int force_multi);
/**
Attempts to rearrange a generic Geometry object into a Polygon or MultiPolygon
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param force_multi if not set to 0, then an eventual Polygon will be
returned casted to MultiPolygon
\return the pointer to newly created Geometry object representing a
Polygon or MultiPolygon Geometry: NULL on failure.
\sa gaiaPolygonize, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaPolygonize_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaPolygonize_r (const void *p_cache,
gaiaGeomCollPtr geom,
int force_multi);
/**
Spatial relationship evalution: Equals
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollEquals_r, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollTouches, gaiaGeomCollRelate
\note Obsolete: not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollEquals (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Equals
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollEquals_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Disjoint
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollDisjoint_r, gaiaGeomCollEquals, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollTouches, gaiaGeomCollRelate
\note Obsolete: not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollDisjoint (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Disjoint
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollDisjoint_r, gaiaGeomCollEquals, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollDisjoint_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Disjoint (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollDisjoint, gaiaGeomCollDisjoint_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedDisjoint (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Intesects
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollIntersects_r, gaiaGeomCollPreparedIntersects,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollOverlaps,
gaiaGeomCollCrosses, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollIntersects (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Intersects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollIntersects, gaiaGeomCollPreparedIntersects,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollOverlaps,
gaiaGeomCollCrosses, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollIntersects_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Intersects (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollIntersects, gaiaGeomCollIntersects_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedIntersects (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Overlaps
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollOverlaps_r, gaiaGeomCollPreparedOverlaps,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollCrosses, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollOverlaps (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Overlaps
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollOverlaps, gaiaGeomCollPreparedOverlaps,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollCrosses, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollOverlaps_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Overlaps (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollOverlaps, gaiaGeomCollOverlaps_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedOverlaps (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Crosses
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollCrosses_r, gaiaGeomCollPreparedCrosses,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCrosses (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Crosses
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollCrosses, gaiaGeomCollPreparedCrosses,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollContains, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCrosses_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Crosses (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\note reentrant and thread-safe.
\sa gaiaGeomCollCrosses, gaiaGeomCollCrosses_r
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedCrosses (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Contains
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollContains_r, gaiaGeomCollPreparedContains,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollContains (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Contains
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollContains, gaiaGeomCollPreparedContains,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollWithin,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollContains_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Contains (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollContains, gaiaGeomCollContains_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedContains (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Within
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollWithin_r, gaiaGeomCollPreparedWithin,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollWithin (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Within
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollWithin, gaiaGeomCollPreparedWithin,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollTouches, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollWithin_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Within (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollWithin, gaiaGeomCollWithin_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedWithin (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Touches
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollTouches_r, gaiaGeomCollPreparedTouches,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollRelate
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollTouches (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Touches
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\return 0 if false: any other value if true
\sa gaiaGeomCollTouches, gaiaGeomCollPreparedTouches,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaGeomCollRelate
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollTouches_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial relationship evalution: Touches (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false: any other value if true
\sa gaiaGeomCollTouches, gaiaGeomCollTouches_r
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedTouches (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Spatial relationship evalution: Relate
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\param pattern intersection matrix pattern [DE-9IM]
\return 0 if false: any other value if true
\sa gaiaGeomCollRelate_r, gaiaGeomCollRelateBoundaryNodeRule,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaIntersectionMatrixPatternMatch
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollRelate (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
const char *pattern);
/**
Spatial relationship evalution: Relate
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\param pattern intersection matrix pattern [DE-9IM]
\return 0 if false: any other value if true
\sa gaiaGeomCollRelate, gaiaGeomCollRelateBoundaryNodeRule_r,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaIntersectionMatrixPatternMatch
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollRelate_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
const char *pattern);
/**
Spatial relationship evalution: Relate Boundary Node Rule
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\param mode can be one of: 1=OGC/MOD2 (default); 2=Endpoint;
3=MultivalentEndpoint; 4=MonovalentEndpoint
\return a DE-9IM intersection matrix; or NULL on invalid geometries.
\sa gaiaGeomCollRelate, gaiaGeomCollRelateBoundaryNodeRule_r,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaIntersectionMatrixPatternMatch
\note you are responsible to destroy (before or after) the intesection
matrix returned by gaiaGeomGeollRelateBoundaryNodeRule()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE char *gaiaGeomCollRelateBoundaryNodeRule (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2, int mode);
/**
Spatial relationship evalution: Relate Boundary Node Rule
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param geom2 the second Geometry object to be evaluated
\param mode can be one of: 1=OGC/MOD2 (default); 2=Endpoint;
3=MultivalentEndpoint; 4=MonovalentEndpoint
\return a DE-9IM intersection matrix; or NULL on invalid geometries.
\sa gaiaGeomCollRelate_r, gaiaGeomCollRelateBoundaryNodeRule,
gaiaGeomCollEquals, gaiaGeomCollDisjoint, gaiaGeomCollIntersects,
gaiaGeomCollOverlaps, gaiaGeomCollCrosses, gaiaGeomCollContains,
gaiaGeomCollWithin, gaiaIntersectionMatrixPatternMatch
\note you are responsible to destroy (before or after) the intesection
matrix returned by gaiaGeomGeollRelateBoundaryNodeRule()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE char *gaiaGeomCollRelateBoundaryNodeRule_r (const void
*p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2,
int mode);
/**
Spatial relationship evalution: comparing two intersection matrices
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param matrix first intersection matrix [DE-9IM] to be compared
\param pattern second intersection matrix [DE-9IM] to be compared\n
(reference pattern)
\return 0 if false: any other value if true; -1 on invalid args
\sa gaiaGeomCollRelateBoundaryNodeRule, gaiaIntersectionMatrixPatternMatch_r
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIntersectionMatrixPatternMatch (const char
*matrix,
const char
*pattern);
/**
Spatial relationship evalution: comparing two intersection matrices
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param matrix first intersection matrix [DE-9IM] to be compared
\param pattern second intersection matrix [DE-9IM] to be compared\n
(reference pattern)
\return 0 if false: any other value if true; -1 on invalid args
\sa gaiaGeomCollRelateBoundaryNodeRule, gaiaIntersectionMatrixPatternMatch
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaIntersectionMatrixPatternMatch_r (const void
*p_cache,
const char
*matrix,
const char
*pattern);
/**
Calculates the maximum distance intercurring between two Geometry objects
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\param dist on completion this variable will contain the calculated distance
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance_r, gaiaGeomCollPreparedDistance,
gaia3DDistance, gaiaMaxDistance, gaia3DMaxDistance
\note this function always computes the 2D cartesian distance.\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollDistance (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Calculates the maximum distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\param dist on completion this variable will contain the calculated distance
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance, gaiaGeomCollPreparedDistance,
gaia3DDistance, gaiaMaxDistance, gaia3DMaxDistance,
gaiaGeomCollPreparedDistanceWithin
\note this function always computes the 2D cartesian distance.\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollDistance_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Spatial relationship evalution: Distance (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\param dist on completion this variable will contain the calculated distance
\return 0 if false: any other value if true
\sa gaiaGeomCollDistance, gaiaGeomCollDistance_r,
gaiaGeomCollPreparedDistanceWithin
\note reentrant and thread-safe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedDistance (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2, double *dist);
/**
Spatial operator: DistanceWithin (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object to be evaluated
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 the second Geometry object to be evaluated
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\param dist the max distance to be checked
\return 0 if false: any other value if true
\sa gaiaGeomCollDistance, gaiaGeomCollDistance_r,
gaiaGeomCollPreparedDistance
\note reentrant and thread-safe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedDistanceWithin (const void *p_cache,
gaiaGeomCollPtr
geom1,
unsigned char
*blob1, int size1,
gaiaGeomCollPtr
geom2,
unsigned char
*blob2, int size2,
double dist);
/**
Spatial operator: Intersection
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Intersection of both input Geometries: NULL on failure.
\sa gaiaGeometryIntersection_r,
gaiaFreeGeomColl, gaiaGeometryUnion, gaiaGeometryDifference,
gaiaGeometrySymDifference, gaiaBoundary
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryIntersection()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryIntersection (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: Intersection
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Intersection of both input Geometries: NULL on failure.
\sa gaiaGeometryIntersection,
gaiaFreeGeomColl, gaiaGeometryUnion, gaiaGeometryDifference,
gaiaGeometrySymDifference, gaiaBoundary
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryIntersection_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryIntersection_r (const void
*p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: Union
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Union of both input Geometries: NULL on failure.
\sa gaiaGeometryUnion_r,
gaiaFreeGeomColl, gaiaUnaryUnion, gaiaUnionCascaded
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryUnion()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryUnion (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Union
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Union of both input Geometries: NULL on failure.
\sa gaiaGeometryUnion,
gaiaFreeGeomColl, gaiaUnaryUnion, gaiaUnionCascaded
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryUnion_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryUnion_r (const void *p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Union Cascaded
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function is similar to gaiaUnaryUnion, but it only accepts Polygons and
MultiPolygons and it's now deprecated; anyway it's supported on older GEOS versions.
NULL on failure.
\sa gaiaUnionCascaded,
gaiaFreeGeomColl, gaiaGeometryUnion, gaiaUnionUnion
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaUnionCascaded()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaUnionCascaded (gaiaGeomCollPtr geom);
/**
Spatial operator: Union Cascaded
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function is similar to gaiaUnaryUnion, but it only accepts Polygons and
MultiPolygons and it's now deprecated; anyway it's supported on older GEOS versions.
NULL on failure.
\sa gaiaUnionCascaded,
gaiaFreeGeomColl, gaiaGeometryUnion, gaiaUnionUnion
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaUnionCascaded_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaUnionCascaded_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Spatial operator: Difference
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Difference of both input Geometries: NULL on failure.
\sa gaiaGeometryDifference_r, gaiaGeometrySymDifference, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryDifference()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryDifference (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: Difference
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry Difference of both input Geometries: NULL on failure.
\sa gaiaGeometryDifference, gaiaGeometrySymDifference, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometryDifference_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometryDifference_r (const void
*p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: SymDifference
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry SymDifference of both input Geometries: NULL on failure.
\sa gaiaGeometrySymDifference_r, gaiaGeometryDifference, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometrySymDifference()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometrySymDifference (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: SymDifference
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\return the pointer to newly created Geometry object representing the
geometry SymDifference of both input Geometries: NULL on failure.
\sa gaiaGeometrySymDifference, gaiaGeometryDifference, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeometrySymDifference_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeometrySymDifference_r (const void
*p_cache,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2);
/**
Spatial operator: Boundary
\param geom the Geometry object to be evaluated
\return the pointer to newly created Geometry object representing the
geometry Boundary of the input Geometry: NULL on failure.
\sa gaiaBoudary_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaBoundary()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaBoundary (gaiaGeomCollPtr geom);
/**
Spatial operator: Boundary
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry object to be evaluated
\return the pointer to newly created Geometry object representing the
geometry Boundary of the input Geometry: NULL on failure.
\sa gaiaBoudary, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaBoundary_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaBoundary_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Spatial operator: Centroid
\param geom pointer to Geometry object.
\param x on completion this variable will contain the centroid X coordinate
\param y on completion this variable will contain the centroid Y coordinate
\return 0 on failure: any other value on success
\sa gaiaGeomCollCentroid_r, gaiaRingCentroid
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCentroid (gaiaGeomCollPtr geom, double *x,
double *y);
/**
Spatial operator: Centroid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object.
\param x on completion this variable will contain the centroid X coordinate
\param y on completion this variable will contain the centroid Y coordinate
\return 0 on failure: any other value on success
\sa gaiaGeomCollCentroid, gaiaRingCentroid
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCentroid_r (const void *p_cache,
gaiaGeomCollPtr geom,
double *x, double *y);
/**
Spatial operator: PointOnSurface
\param geom pointer to Geometry object.
\param x on completion this variable will contain the Point X coordinate
\param y on completion this variable will contain the Point Y coordinate
\return 0 on failure: any other value on success
\sa gaiaGetPointOnSurface_r
\note not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGetPointOnSurface (gaiaGeomCollPtr geom,
double *x, double *y);
/**
Spatial operator: PointOnSurface
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object.
\param x on completion this variable will contain the Point X coordinate
\param y on completion this variable will contain the Point Y coordinate
\return 0 on failure: any other value on success
\sa gaiaGetPointOnSurface
\note reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE int gaiaGetPointOnSurface_r (const void *p_cache,
gaiaGeomCollPtr geom,
double *x, double *y);
/**
Spatial operator: Simplify
\param geom the input Geometry object
\param tolerance approximation threshold
\return the pointer to newly created Geometry object representing the
simplified Geometry [applying the Douglas-Peucker algorithm]: NULL on failure.
\sa gaiaGeomCollSimplify_r,
gaiaFreeGeomColl, gaiaGeomCollSimplifyPreserveTopology
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollSimplify()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeomCollSimplify (gaiaGeomCollPtr
geom,
double tolerance);
/**
Spatial operator: Simplify
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param tolerance approximation threshold
\return the pointer to newly created Geometry object representing the
simplified Geometry [applying the Douglas-Peucker algorithm]: NULL on failure.
\sa gaiaGeomCollSimplify,
gaiaFreeGeomColl, gaiaGeomCollSimplifyPreserveTopology
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollSimplify_r()\n
reentrant and thread safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeomCollSimplify_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
double tolerance);
/**
Spatial operator: Simplify [preserving topology]
\param geom the input Geometry object
\param tolerance approximation threshold
\return the pointer to newly created Geometry object representing the
simplified Geometry [applying the Douglas-Peucker algorithm]: NULL on failure.
\sa gaiaGeomCollSimplifyPreserveTopology_r,
gaiaFreeGeomColl, gaiaGeomCollSimplify
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollSimplify()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplifyPreserveTopology (gaiaGeomCollPtr geom,
double tolerance);
/**
Spatial operator: Simplify [preserving topology]
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param tolerance approximation threshold
\return the pointer to newly created Geometry object representing the
simplified Geometry [applying the Douglas-Peucker algorithm]: NULL on failure.
\sa gaiaGeomCollSimplifyPreserveTopology,
gaiaFreeGeomColl, gaiaGeomCollSimplify
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollSimplify_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplifyPreserveTopology_r (const void *p_cache,
gaiaGeomCollPtr geom,
double tolerance);
/**
Spatial operator: ConvexHull
\param geom the input Geometry object
\return the pointer to newly created Geometry object representing the
ConvexHull of input Geometry: NULL on failure.
\sa gaiaConvexHull_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConvexHull()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaConvexHull (gaiaGeomCollPtr geom);
/**
Spatial operator: ConvexHull
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\return the pointer to newly created Geometry object representing the
ConvexHull of input Geometry: NULL on failure.
\sa gaiaConvexHull, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConvexHull_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaConvexHull_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Spatial operator: Buffer
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\return the pointer to newly created Geometry object representing the
Buffer of input Geometry: NULL on failure.
\sa gaiaGeomCollBuffer_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollBuffer()\n
not reentrant and thread unsafe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeomCollBuffer (gaiaGeomCollPtr geom,
double radius,
int points);
/**
Spatial operator: Buffer
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\return the pointer to newly created Geometry object representing the
Buffer of input Geometry: NULL on failure.
\sa gaiaGeomCollBuffer, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeomCollBuffer_r()\n
reentrant and thread-safe.
\remark \b GEOS support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeomCollBuffer_r (const void *p_cache,
gaiaGeomCollPtr
geom, double radius,
int points);
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef GEOS_ADVANCED
#endif
/**
Calculates the Hausdorff distance intercurring between two Geometry objects
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param dist on completion this variable will contain the calculated Hausdorff
distance
\return 0 on failure: any other value on success.
\sa gaiaHausdorffDistance_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaHausdorffDistance (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Calculates the Hausdorff distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param dist on completion this variable will contain the calculated Hausdorff
distance
\return 0 on failure: any other value on success.
\sa gaiaHausdorffDistance
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaHausdorffDistance_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Calculates the Hausdorff distance intercurring between two Geometry objects
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param densify_fract fraction (in the range 0.0 / 1.0) by which to densify
each segment. Each segment will be split into a number of equal-lenght
subsegments, whose fraction of the total length is closest to the given
fraction
\param dist on completion this variable will contain the calculated Hausdorff
distance
\return 0 on failure: any other value on success.
\sa gaiaHausdorffDistance_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaHausdorffDistanceDensify (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double densify_fract,
double *dist);
/**
Calculates the Hausdorff distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param densify_fract fraction (in the range 0.0 / 1.0) by which to densify
each segment. Each segment will be split into a number of equal-lenght
subsegments, whose fraction of the total length is closest to the given
fraction
\param dist on completion this variable will contain the calculated Hausdorff
distance
\return 0 on failure: any other value on success.
\sa gaiaHausdorffDistance
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaHausdorffDistanceDensify_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double densify_fract,
double *dist);
/**
Calculates the Frechet distance intercurring between two Geometry objects
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param dist on completion this variable will contain the calculated Frechet
distance
\return 0 on failure: any other value on success.
\sa gaiaFrechetDistance_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaFrechetDistance (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Calculates the Frechet distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param dist on completion this variable will contain the calculated Frechet
distance
\return 0 on failure: any other value on success.
\sa gaiaFrechetDistance
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaFrechetDistance_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double *dist);
/**
Calculates the Frechet distance intercurring between two Geometry objects
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param densify_fract fraction (in the range 0.0 / 1.0) by which to densify
each segment. Each segment will be split into a number of equal-lenght
subsegments, whose fraction of the total length is closest to the given
fraction
\param dist on completion this variable will contain the calculated Frechet
distance
\return 0 on failure: any other value on success.
\sa gaiaFrechetDistance_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaFrechetDistanceDensify (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double densify_fract,
double *dist);
/**
Calculates the Frechet distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\param densify_fract fraction (in the range 0.0 / 1.0) by which to densify
each segment. Each segment will be split into a number of equal-lenght
subsegments, whose fraction of the total length is closest to the given
fraction
\param dist on completion this variable will contain the calculated Frechet
distance
\return 0 on failure: any other value on success.
\sa gaiaFrechetDistance
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaFrechetDistanceDensify_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double densify_fract,
double *dist);
/**
Calculates the minimum rotated rectangular POLYGON which encloses the input geometry
\param geom pointer to input Geometry object
\return NULL on failure: the minimum rotated rectangle on success.
\sa gaiaMinimumRotatedRectangle_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumRotatedRectangle (gaiaGeomCollPtr
geom);
/**
Calculates the minimum rotated rectangular POLYGON which encloses the input geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\return NULL on failure: the minimum rotated rectangle on success.
\sa gaiaMinimumRotatedRectangle
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumRotatedRectangle_r (const void
*p_cache,
gaiaGeomCollPtr
geom);
/**
Constructs the Maximum Inscribed Circle for a polygonal geometry, up to a specified tolerance.
\param geom pointer to input Geometry object
\param tolerance approximation factor
\return NULL on failure: the maximum inscribed circle on success.
\sa gaiaMaximumInscribedCircle_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMaximumInscribedCircle (gaiaGeomCollPtr
geom,
double
tolerance);
/**
Constructs the Maximum Inscribed Circle for a polygonal geometry, up to a specified tolerance.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\param tolerance approximation factor
\return 0 on failure: the maximum inscribed circle on success.
\sa gaiaMaximumInscribedCircle
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMaximumInscribedCircle_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
double
tolerance);
/**
Constructs the Minimum Bounding Circle for a generic geometry.
\param geom pointer to input Geometry object
\param radius on completion this variable will contain the radius of the circle
\param center on completion this variable will contain the cntre of the circle
(POINT Geometry)
\return NULL on failure: the minimum bounding circle on success.
\sa gaiaMinimumBoundingCircle_r
\note not reentrant and thread unsafe.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including the Geometry returned by gaiaMinumumBoundingCircle() and the
POINT Geometry corresponding to the Center
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumBoundingCircle (gaiaGeomCollPtr
geom,
double *radius,
gaiaGeomCollPtr *
center);
/**
Constructs the Minimum Bounding Circle for a generic geometry.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\param radius on completion this variable will contain the radius of the circle
\param center on completion this variable will contain the cntre of the circle
(POINT Geometry)
\return NULL on failure: the minimum bounding circle on success.
\sa gaiaMinimumBoundingCircle
\note reentrant and thread-safe.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including the Geometry returned by gaiaMinumumBoundingCircle() and the
POINT Geometry corresponding to the Center
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumBoundingCircle_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
double *radius,
gaiaGeomCollPtr
* center);
/**
Constructs the Largest Empty Circle for a set of obstacle geometries, up to a specified tolerance.
\param geom pointer to input Geometry object
\param tolerance approximation factor
\return NULL on failure: the maximum inscribed circle on success.
\sa gaiaLargestEmptyCircle_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLargestEmptyCircle (gaiaGeomCollPtr
geom,
gaiaGeomCollPtr
boundary,
double tolerance);
/**
Constructs the Largest Empty Circle for a set of obstacle geometries, up to a specified tolerance.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\param tolerance approximation factor
\return NULL on failure: the maximum inscribed circle on success.
\sa gaiaLargestEmptyCircle
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLargestEmptyCircle_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
gaiaGeomCollPtr
boundary,
double tolerance);
/**
Returns a LINESTRING geometry which represents the minimum diameter of the geometry
\param geom pointer to input Geometry object
\return NULL on failure: the minimum width Linestring on success.
\sa gaiaMinimumWidth_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumWidth (gaiaGeomCollPtr geom);
/**
Returns a LINESTRING geometry which represents the minimum diameter of the geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\return NULL on failure: the minimum width Linestring on success.
\sa gaiaMinimumWidth
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumWidth_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Computes the minimum clearance of a geometry.
\param geom pointer to input Geometry object
\param clearance on succesfull completion this pointer will reference the
computed clearance value
\return ZERO (0) on failure: any other value on success
\sa gaiaMinimumClearance_r, gaiaMinimumClearanceLine, gaiaMinimumClearanceLine_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaMinimumClearance (gaiaGeomCollPtr geom,
double *clearance);
/**
Computes the minimum clearance of a geometry.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\param clearance on succesfull completion this pointer will reference the
computed clearance value
\return ZERO (0) on failure: any other value on success
\sa gaiaMinimumClearance_r, gaiaMinimumClearanceLine, gaiaMinimumClearanceLine_r
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaMinimumClearance_r (const void *p_cache,
gaiaGeomCollPtr geom,
double *clearance);
/**
Returns a LINESTRING geometry which represents the minimum clearance of a geometry
\param geom pointer to input Geometry object
\return NULL on failure: the minimum clearance Linestring on success.
\sa gaiaMinimumClearance, gaiaMinimumClearance_r, gaiaMinimumClearanceLine_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumClearanceLine (gaiaGeomCollPtr
geom);
/**
Returns a LINESTRING geometry which represents the minimum clearance of a geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object
\return NULL on failure: the minimum clearance Linestring on success.
\sa gaiaMinimumClearance, gaiaMinimumClearance_r, gaiaMinimumClearanceLine
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMinimumClearanceLine_r (const void
*p_cache,
gaiaGeomCollPtr
geom);
/**
Spatial operator: Offset Curve
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\param left_right if set to 1 the left-sided OffsetCurve will be returned;
otherwise the right-sided one.
\return the pointer to newly created Geometry object representing the
OffsetCurve of input Geometry: NULL on failure.
\sa gaiaOffsetCurve_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaOffsetCurve()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaOffsetCurve (gaiaGeomCollPtr geom,
double radius,
int points,
int left_right);
/**
Spatial operator: Offset Curve
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\param left_right if set to 1 the left-sided OffsetCurve will be returned;
otherwise the right-sided one.
\return the pointer to newly created Geometry object representing the
OffsetCurve of input Geometry: NULL on failure.
\sa gaiaOffsetCurve, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaOffsetCurve_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaOffsetCurve_r (const void *p_cache,
gaiaGeomCollPtr geom,
double radius,
int points,
int left_right);
/**
Spatial operator: Single Sided Buffer
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\param left_right if set to 1 the left-sided Buffer will be returned;
otherwise the right-sided one.
\return the pointer to newly created Geometry object representing the
single-sided Buffer of input Geometry: NULL on failure.
\sa gaiaSingleSidedBuffer_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSingleSidedBuffer()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSingleSidedBuffer (gaiaGeomCollPtr
geom,
double radius,
int points,
int left_right);
/**
Spatial operator: Single Sided Buffer
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object
\param radius the buffer's radius
\param points number of points (aka vertices) to be used in order to
approximate a circular arc.
\param left_right if set to 1 the left-sided Buffer will be returned;
otherwise the right-sided one.
\return the pointer to newly created Geometry object representing the
single-sided Buffer of input Geometry: NULL on failure.
\sa gaiaSingleSidedBuffer, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSingleSidedBuffer_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSingleSidedBuffer_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
double radius,
int points,
int left_right);
/**
Spatial operator: Shared Paths
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\return the pointer to newly created Geometry object representing any
Share Path common to both input geometries: NULL on failure.
\sa gaiaSharedPaths_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSharedPaths()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSharedPaths (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Shared Paths
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first Geometry object
\param geom2 pointer to second Geometry object
\return the pointer to newly created Geometry object representing any
Share Path common to both input geometries: NULL on failure.
\sa gaiaSharedPaths, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSharedPaths_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSharedPaths_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Line Interpolate Point
\param ln_geom the input Geometry object [expected to be of lineal type]
\param fraction total length fraction [in the range 0.0 / 1.0]
\return the pointer to newly created Geometry object representing a Point
laying on the input Geometry and positioned at the given length fraction:
NULL on failure.
\sa gaiaLineInterpolatePoint_r,
gaiaLineInterpolateEquidistantPoints, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineInterpolatePoint()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineInterpolatePoint (gaiaGeomCollPtr
ln_geom,
double fraction);
/**
Spatial operator: Line Interpolate Point
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param ln_geom the input Geometry object [expected to be of lineal type]
\param fraction total length fraction [in the range 0.0 / 1.0]
\return the pointer to newly created Geometry object representing a Point
laying on the input Geometry and positioned at the given length fraction:
NULL on failure.
\sa gaiaLineInterpolatePoint,
gaiaLineInterpolateEquidistantPoints, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineInterpolatePoint_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineInterpolatePoint_r (const void
*p_cache,
gaiaGeomCollPtr
ln_geom,
double
fraction);
/**
Spatial operator: Line Interpolate Equidistant Points
\param ln_geom the input Geometry object [expected to be of lineal type]
\param distance regular distance between interpolated points
\return the pointer to newly created Geometry object representing a MultiPoint;
such MultiPoint always supports the M coordinate (the corresponding value
representing the progressive distance for each interpolated Point).
individual Points will be regularly spaced by the given distance:
NULL on failure.
\sa gaiaLineInterpolateEquidistantPoints_r,
gaiaLineInterpolatePoint, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineInterpolateEquidistantPoints()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolateEquidistantPoints (gaiaGeomCollPtr ln_geom,
double distance);
/**
Spatial operator: Line Interpolate Equidistant Points
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param ln_geom the input Geometry object [expected to be of lineal type]
\param distance regular distance between interpolated points
\return the pointer to newly created Geometry object representing a MultiPoint;
such MultiPoint always supports the M coordinate (the corresponding value
representing the progressive distance for each interpolated Point).
individual Points will be regularly spaced by the given distance:
NULL on failure.
\sa gaiaLineInterpolateEquidistantPoints,
gaiaLineInterpolatePoint, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineInterpolateEquidistantPoints_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolateEquidistantPoints_r (const void *p_cache,
gaiaGeomCollPtr ln_geom,
double distance);
/**
Spatial operator: Line Substring
\param ln_geom the input Geometry object [expected to be of lineal type]
\param start_fraction substring start, expressed as total length fraction
[in the range 0.0 / 1.0]
\param end_fraction substring end, expressed as total length fraction
\return the pointer to newly created Geometry object representing a Linestring
laying on the input Geometry.
\n this Linestring will begin (and stop) at given total length fractions.
NULL on failure.
\sa gaiaLineSubstring_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineSubstring()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineSubstring (gaiaGeomCollPtr
ln_geom,
double start_fraction,
double end_fraction);
/**
Spatial operator: Line Substring
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param ln_geom the input Geometry object [expected to be of lineal type]
\param start_fraction substring start, expressed as total length fraction
[in the range 0.0 / 1.0]
\param end_fraction substring end, expressed as total length fraction
\return the pointer to newly created Geometry object representing a Linestring
laying on the input Geometry.
\n this Linestring will begin (and stop) at given total length fractions.
NULL on failure.
\sa gaiaLineSubstring, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineSubstring_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineSubstring_r (const void *p_cache,
gaiaGeomCollPtr
ln_geom,
double
start_fraction,
double end_fraction);
/**
Spatial operator: Shortest Line
\param geom1 pointer to the first Geometry object.
\param geom2 pointer to the second Geometry object.
\return the pointer to newly created Geometry object representing a Linestring;
NULL on failure.
\n the returned Linestring graphically represents the minimum distance
intercurrinng between both input geometries.
\sa gaiaShortestLine_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaShortestLine()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaShortestLine (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Shortest Line
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to the first Geometry object.
\param geom2 pointer to the second Geometry object.
\return the pointer to newly created Geometry object representing a Linestring;
NULL on failure.
\n the returned Linestring graphically represents the minimum distance
intercurrinng between both input geometries.
\sa gaiaShortestLine, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaShortestLine_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaShortestLine_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Snap
\param geom1 pointer to the first Geometry object.
\param geom2 pointer to the second Geometry object.
\param tolerance approximation factor
\return the pointer to newly created Geometry object; NULL on failure.
\n the returned Geometry represents the first input Geometry (nicely
\e snapped to the second input Geometry, whenever is possible).
\sa gaiaSnap_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSnap()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSnap (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double tolerance);
/**
Spatial operator: Snap
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to the first Geometry object.
\param geom2 pointer to the second Geometry object.
\param tolerance approximation factor
\return the pointer to newly created Geometry object; NULL on failure.
\n the returned Geometry represents the first input Geometry (nicely
\e snapped to the second input Geometry, whenever is possible).
\sa gaiaSnap, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSnap_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSnap_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double tolerance);
/**
Spatial operator: Line Merge
\param geom pointer to input Geometry object.
\return the pointer to newly created Geometry object; NULL on failure.
\n if possible, this representing a reassembled Linestring or MultiLinestring.
\sa gaiaLineMerge_r, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineMerge()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineMerge (gaiaGeomCollPtr geom);
/**
Spatial operator: Line Merge
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\return the pointer to newly created Geometry object; NULL on failure.
\n if possible, this representing a reassembled Linestring or MultiLinestring.
\sa gaiaLineMerge, gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLineMerge_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineMerge_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Spatial operator: Line Cut At Nodes
\param geom1 pointer to input Geometry object [Linestring or MultiLinestring].
\param geom2 pointer to input Geometry object [Point or MultiPoint].
\return the pointer to newly created Geometry object; NULL on failure.
\n if possible, any input Linestring will be split accordingly to given Node(s):
no point will be interpolated, existing Linestring Vertices will be evaluated.
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaLinesCutAtNodes()
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLinesCutAtNodes (gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr geom2);
/**
Spatial operator: Unary Union
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function is the same as gaiaGeometryUnion, except in that this
works internally to the input Geometry itself.
NULL on failure.
\sa gaiaUnaryUnion_r, gaiaFreeGeomColl, gaiaGeometryUnion, gaiaUnionCascaded
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaUnaryUnion()\n
not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaUnaryUnion (gaiaGeomCollPtr geom);
/**
Spatial operator: Unary Union
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function is the same as gaiaGeometryUnion, except in that this
works internally to the input Geometry itself.
NULL on failure.
\sa gaiaUnaryUnion, gaiaFreeGeomColl, gaiaGeometryUnion, gaiaUnionCascaded
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaUnaryUnion_r()\n
reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaUnaryUnion_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Determines the location of the closest Point on Linestring to the given Point
\param ln_geom pointer to first input Geometry object [expected to be of
the lineal type].
\param pt_geom pointer to second input Geometry object [expected to be a
Point].
\return the fraction [in the range 0.0 / 1.0] of ln_geom total length
where the closest Point to pt_geom lays.
\sa gaiaLineLocatePoint_r
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE double gaiaLineLocatePoint (gaiaGeomCollPtr ln_geom,
gaiaGeomCollPtr pt_geom);
/**
Determines the location of the closest Point on Linestring to the given Point
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param ln_geom pointer to first input Geometry object [expected to be of
the lineal type].
\param pt_geom pointer to second input Geometry object [expected to be a
Point].
\return the fraction [in the range 0.0 / 1.0] of ln_geom total length
where the closest Point to pt_geom lays.
\sa gaiaLineLocatePoint
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE double gaiaLineLocatePoint_r (const void *p_cache,
gaiaGeomCollPtr ln_geom,
gaiaGeomCollPtr pt_geom);
/**
Topology check: test if a Geometry covers another one
\param geom1 pointer to first input Geometry object.
\param geom2 pointer to second input Geometry object.
\return 0 if false; any other value if geom1 \e spatially \e covers geom2.
\sa gaiaGeomCollCovers_r, gaiaGeomCollPreparedCovers, gaiaGeomCollCoveredBy
\note not reentrant and thead unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCovers (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Topology check: test if a Geometry covers another one
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first input Geometry object.
\param geom2 pointer to second input Geometry object.
\return 0 if false; any other value if geom1 \e spatially \e covers geom2.
\sa gaiaGeomCollCovers, gaiaGeomCollPreparedCovers, gaiaGeomCollCoveredBy
\note reentrant and thead-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCovers_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Topology check: test if a Geometry covers another one (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first input Geometry object.
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 pointer to second input Geometry object.
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false; any other value if geom1 \e spatially \e covers geom2.
\note reentrant and thread-safe.
\sa gaiaGeomCollCovers, gaiaGeomCollCovers_r
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedCovers (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Topology check: test if a Geometry is covered by another one
\param geom1 pointer to first input Geometry object.
\param geom2 pointer to second input Geometry object.
\return 0 if false; any other value if geom2 is \e spatially \e covered \e by
geom1.
\sa gaiaGeomCollCoveredBy_r, gaiaGeomCollPreparedCoveredBy, gaiaGeomCollCovers
\note not reentrant and thread unsafe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCoveredBy (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Topology check: test if a Geometry is covered by another one
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first input Geometry object.
\param geom2 pointer to second input Geometry object.
\return 0 if false; any other value if geom2 is \e spatially \e covered \e by
geom1.
\sa gaiaGeomCollCoveredBy, gaiaGeomCollPreparedCoveredBy, gaiaGeomCollCovers
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollCoveredBy_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2);
/**
Topology check: test if a Geometry is covered by another one (GEOSPreparedGeometry)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 pointer to first input Geometry object.
\param blob1 the BLOB corresponding to the first Geometry
\param size1 the size (in bytes) of the first BLOB
\param geom2 pointer to second input Geometry object.
\param blob2 the BLOB corresponding to the second Geometry
\param size2 the size (in bytes) of the second BLOB
\return 0 if false; any other value if geom2 is \e spatially \e covered \e by
geom1.
\sa gaiaGeomCollCoveredBy, gaiaGeomCollCoveredBy_r, gaiaGeomCollCovers
\note reentrant and thread-safe.
\remark \b GEOS-ADVANCED support required.
*/
GAIAGEO_DECLARE int gaiaGeomCollPreparedCoveredBy (const void *p_cache,
gaiaGeomCollPtr geom1,
unsigned char *blob1,
int size1,
gaiaGeomCollPtr geom2,
unsigned char *blob2,
int size2);
/**
Utility function: SquareGrid
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
square POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaSquareGrid_r, gaiaFreeGeomColl, gaiaTriangularGrid, gaiaHexagonalGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSquareGrid()\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSquareGrid (gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double size, int mode);
/**
Utility function: SquareGrid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
square POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaSquareGrid, gaiaFreeGeomColl, gaiaTriangularGrid, gaiaHexagonalGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSquareGrid_r()\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSquareGrid_r (const void *p_cache,
gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double size, int mode);
/**
Utility function: TriangularGrid
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
triangular POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaTriangularGrid_r, gaiaFreeGeomColl, gaiaSquareGrid, gaiaHexagonalGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaTriangularGrid()\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTriangularGrid (gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double size, int mode);
/**
Utility function: TriangularGrid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
riangular POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaTriangularGrid, gaiaFreeGeomColl, gaiaSquareGrid, gaiaHexagonalGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaTriangularGrid_r()\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaTriangularGrid_r (const void *p_cache,
gaiaGeomCollPtr
geom,
double origin_x,
double origin_y,
double size,
int mode);
/**
Utility function: HexagonalGrid
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
hexagonal POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaGexagonalGrid_r, gaiaFreeGeomColl, gaiaSquareGrid, gaiaTriangularGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaHexagonalGrid()\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaHexagonalGrid (gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double size, int mode);
/**
Utility function: HexagonalGrid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry to be covered by the Grid.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param size the Grid cell-side size.
\param mode any positive value will return a MULTILINESTRING, any will
return a MULTIPOINT; zero will return a MULTIPOLYGON containing
hexagonal POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will always return a MultiPolygon
\n NULL will be returned if any argument is invalid.
\sa gaiaGexagonalGrid, gaiaFreeGeomColl, gaiaSquareGrid, gaiaTriangularGrid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaHexagonalGrid_r()\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaHexagonalGrid_r (const void *p_cache,
gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double size, int mode);
#endif /* end GEOS advanced features */
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef GEOS_3100
#endif
/**
Densifies a geometry using a given distance tolerance
\param geom pointer to input Geometry object.
\param tolerance the distance tolerance to densify.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaGeosDensify_r,
gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosDensify()\n
not reentrant and thread unsafe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosDensify (gaiaGeomCollPtr
geom, double tolerance);
/**
Densifies a geometry using a given distance tolerance
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\param tolerance the distance tolerance to densify.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaGeosDensify,
gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosDensify_r()\n
reentrant and thread-safe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosDensify_r (const void
*p_cache,
gaiaGeomCollPtr
geom, double tolerance);
/**
Constrained Delaunay Triangulation
\param geom pointer to input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid or if the input
geometry does not contain any Polygon.
\sa gaiaConstrainedDelaunayTriangulation_r,
gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConstrainedDelaunayTriangulation()\n
not reentrant and thread unsafe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConstrainedDelaunayTriangulation (gaiaGeomCollPtr geom);
/**
Constrained Delaunay Triangulation
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid or if the input
geometry does not contain any Polygon.
\sa gaiaConstrainedDelaunayTriangulation,
gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConstrainedDelaunayTriangulation_r()\n
reentrant and thread-safe.
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConstrainedDelaunayTriangulation_r (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Utility function: GeosMakeValid
\param geom the input Geometry object.
\param keep_discarded boolean: if FALSE all geometry components that
collapse to a lower dimensionality, for example a one-point linestring,
will be dropped.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will attempt to create a valid representation of a given
invalid geometry using the GEOS own "method=structure".
\sa gaiaFreeGeomColl, gaiaMakeValid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosMakeValid()
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosMakeValid (gaiaGeomCollPtr geom,
int keep_discarded);
/**
Utility function: GeosMakeValid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\param keep_discarded boolean: if FALSE all geometry components that
collapse to a lower dimensionality, for example a one-point linestring,
will be dropped.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will attempt to create a valid representation of a given
invalid geometry using the GEOS own "method=structure".
\sa gaiaFreeGeomColl, gaiaMakeValid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosMakeValid()
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosMakeValid_r (const void *p_cache,
gaiaGeomCollPtr geom,
int keep_discarded);
/**
Change the coordinate precision of a geometry.
\param geom the input Geometry object.
\param grid_size the gridSize cell size of grid to round coordinates to,
or 0 for FLOATING precision
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaFreeGeomColl, gaiaReducePrecision_r
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaReducePrecision()
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaReducePrecision (gaiaGeomCollPtr geom,
double grid_size);
/**
Change the coordinate precision of a geometry.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\param grid_size the gridSize cell size of grid to round coordinates to,
or 0 for FLOATING precision
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaFreeGeomColl, gaiaReducePrecision
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaReducePrecision()
\remark \b GEOS_3100 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaReducePrecision_r (const void *p_cache,
gaiaGeomCollPtr geom,
double grid_size);
#endif /* end GEOS_3100 features */
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef GEOS_3110
#endif
/**
Hillbert Code
\param geom1 the input Geometry object.
\param geom2 the Extent
\param level integer precision level of the Hilbert Curve [1-16]
\param code pointer to an unsigned int where to store the calculated Hilbert Code
\return 1 on success, 0 on failure.
\sa gaiaHilbertCode_r
\remark \b GEOS_3110 support required.
*/
GAIAGEO_DECLARE int gaiaHilbertCode (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, int level,
unsigned int *code);
/**
Hillbert Code
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the input Geometry object.
\param geom2 the Extent
\param level integer precision level of the Hilbert Curve [1-16]
\param code pointer to an unsigned int where to store the calculated Hilbert Code
\return 1 on success, 0 on failure.
\sa gaiaHilbertCode
\remark \b GEOS_3110 support required.
*/
GAIAGEO_DECLARE int gaiaHilbertCode_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, int level,
unsigned int *code);
/**
Concave Hull (the GEOS way)
\param geom pointer to input Geometry object.
\param ratio an index ranging from 1.0 (Convex Hull) to 0.0 (maximum concaveness).
\param allow_holes if FALSE any interior hole will be suppressed.
\return the pointer to newly created Geometry object (always of the Polygon type):
NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaGeosConcaveHull_r, gaiaFreeGeomColl, gaiaConcaveHull, gaiaConcaveHull_r
\note This function is directly based on GEOSConcaveHull().
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosConcaveHull()\n
not reentrant and thread unsafe.
\remark \b GEOS_3110 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosConcaveHull (gaiaGeomCollPtr geom,
double ratio,
int allow_holes);
/**
Concave Hull (the GEOS way)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\param ratio an index ranging from 1.0 (Convex Hull) to 0.0 (maximum concaveness).
\param allow_holes if FALSE any interior hole will be suppressed.
\return the pointer to newly created Geometry object (always of the Polygon type):
NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaGeosConcaveHull, gaiaFreeGeomColl, gaiaConcaveHull, gaiaConcaveHull_r
\note This function is directly based on GEOSConcaveHull_r().
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaGeosConcaveHull_r()\n
reentrant and thread-safe.
\remark \b GEOS_3110 support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaGeosConcaveHull_r (const void *p_cache,
gaiaGeomCollPtr geom,
double ratio,
int allow_holes);
#endif /* end GEOS_3110 features */
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef GEOS_TRUNK
#endif
/**
Delaunay Triangulation
\param geom pointer to input Geometry object.
\param tolerance optional snapping tolerance.
\param only_edges if non-zero will return a MULTILINESTRING, otherwise it will
return a MULTIPOLYGON containing triangular POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaDelaunayTriangulation_r,
gaiaFreeGeomColl, gaiaVoronojDiagram, gaiaConcaveHull
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaDelaunayTriangulation()\n
not reentrant and thread unsafe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDelaunayTriangulation (gaiaGeomCollPtr
geom,
double
tolerance,
int only_edges);
/**
Delaunay Triangulation
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\param tolerance optional snapping tolerance.
\param only_edges if non-zero will return a MULTILINESTRING, otherwise it will
return a MULTIPOLYGON containing triangular POLYGONs.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaDelaunayTriangulation,
gaiaFreeGeomColl, gaiaVoronojDiagram, gaiaConcaveHull
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaDelaunayTriangulation_r()\n
reentrant and thread-safe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDelaunayTriangulation_r (const void
*p_cache,
gaiaGeomCollPtr
geom,
double
tolerance,
int
only_edges);
/**
Voronoj Diagram
\param geom pointer to input Geometry object.
\param extra_frame_size percent factor expanding the BBOX of input Geometry
\param tolerance optional snapping tolerance.
\param only_edges if non-zero will return a MULTILINESTRING, otherwise it will
return a MULTIPOLYGON.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaVoronojDiagram_r, gaiaFreeGeomColl, gaiaDelaunayTriangulation
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaVoronojDiagram()\n
not reentrant and thread unsafe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaVoronojDiagram (gaiaGeomCollPtr geom,
double
extra_frame_size,
double tolerance,
int only_edges);
/**
Voronoj Diagram
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\param extra_frame_size percent factor expanding the BBOX of input Geometry
\param tolerance optional snapping tolerance.
\param only_edges if non-zero will return a MULTILINESTRING, otherwise it will
return a MULTIPOLYGON.
\return the pointer to newly created Geometry object: NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaVoronojDiagram, gaiaFreeGeomColl, gaiaDelaunayTriangulation
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaVoronojDiagram_r()\n
reentrant and thread-safe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaVoronojDiagram_r (const void *p_cache,
gaiaGeomCollPtr
geom,
double
extra_frame_size,
double tolerance,
int only_edges);
/**
Concave Hull
\param geom pointer to input Geometry object.
\param factor multiplier used for filtering Delaunay triangles: please read the note.
\param tolerance optional snapping tolerance.
\param allow_holes if FALSE any interior hole will be suppressed.
\return the pointer to newly created Geometry object (always of the Polygon type):
NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaConcaveHull_r, gaiaFreeGeomColl, gaiaDelaunayTriangulation, gaiaGeosConcaveHull, gaiaGeosConcaveHull_r
\note This function will first create the Delauany Triangulation corresponding
to input Geometry, determining at the same time the \b standard \b deviation
for all edge's lengths.
\n Then in a second pass all Delaunay's triangles will be filtered, and all
triangles presenting at least one edge longer than \b standard \b deviation
\b * \b factor will be discarded.
\n All filtered triangles will then be merged altogether so to create the Concave Hull.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConcaveHull()\n
not reentrant and thread unsafe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaConcaveHull (gaiaGeomCollPtr geom,
double factor,
double tolerance,
int allow_holes);
/**
Concave Hull
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to input Geometry object.
\param factor multiplier used for filtering Delaunay triangles: please read the note.
\param tolerance optional snapping tolerance.
\param allow_holes if FALSE any interior hole will be suppressed.
\return the pointer to newly created Geometry object (always of the Polygon type):
NULL on failure.
\n NULL will be returned if any argument is invalid.
\sa gaiaConcaveHull, gaiaFreeGeomColl, gaiaDelaunayTriangulation, gaiaGeosConcaveHull, gaiaGeosConcaveHull_r
\note This function will first create the Delauany Triangulation corresponding
to input Geometry, determining at the same time the \b standard \b deviation
for all edge's lengths.
\n Then in a second pass all Delaunay's triangles will be filtered, and all
triangles presenting at least one edge longer than \b standard \b deviation
\b * \b factor will be discarded.
\n All filtered triangles will then be merged altogether so to create the Concave Hull.
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaConcaveHull_r()\n
reentrant and thread-safe.
\remark \b GEOS-TRUNK support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaConcaveHull_r (const void *p_cache,
gaiaGeomCollPtr geom,
double factor,
double tolerance,
int allow_holes);
#endif /* end GEOS experimental features */
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef ENABLE_RTTOPO
#endif
/**
Resets the RTTOPO error and warning messages to an empty state
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\sa gaiaGetRtTopoErrorMsg, gaiaGetRtTopoWarningMsg, gaiaSetRtTopoErrorMsg,
gaiaSetRtTopoWarningMsg
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE void gaiaResetRtTopoMsg (const void *p_cache);
/**
Return the latest RTTOPO error message (if any)
\return the latest RTTOPO error message: an empty string if no error was
previoysly found.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\sa gaiaResetRtTopoMsg, gaiaGetRtTopoWarningMsg, gaiaSetRtTopoErrorMsg,
gaiaSetRtTopoWarningMsg
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE const char *gaiaGetRtTopoErrorMsg (const void *p_cache);
/**
Return the latest RTTOPO warning message (if any)
\return the latest RTTOPO warning message: an empty string if no warning was
previoysly found.
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\sa gaiaResetRtTopoMsg, gaiaGetRtTopoErrorMsg, gaiaSetRtTopoErrorMsg,
gaiaSetRtTopoWarningMsg
\note not reentrant and thread unsafe.
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE const char *gaiaGetRtTopoWarningMsg (const void *p_cache);
/**
Set the current RTTOPO error message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the error message to be set.
\sa gaiaResetRtTopoMsg, gaiaGetRtTopoErrorMsg, gaiaGetRtTopoWarningMsg,
gaiaSetRtTopoWarningMsg
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE void gaiaSetRtTopoErrorMsg (const void *p_cache,
const char *msg);
/**
Set the current RTTOPO warning message
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param msg the warning message to be set.
\sa gaiaResetRtTopoMsg, gaiaGetRtTopoErrorMsg, gaiaGetRtTopoWarningMsg,
gaiaSetRtTopoErrorMsg
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE void gaiaSetRtTopoWarningMsg (const void *p_cache,
const char *msg);
/**
Utility function: MakeValid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will attempt to create a valid representation of a given
invalid geometry without loosing any of the input vertices.
\n Already-valid geometries are returned without further intervention.
\n NULL will be returned if the passed argument is invalid.
\sa gaiaFreeGeomColl, gaiaMakeValidDiscarded, gaiaGeosMakeValid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaMakeValid()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeValid (const void *p_cache,
gaiaGeomCollPtr geom);
/**
Utility function: MakeValidDiscarded
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will attempt to collect any invalid item (offending
geometries) discarded by gaiaMakeValid while building a valid Geometry.
\n Saving any discarded item could be useful for a finer (manual) adjustment.
\n NULL will be returned if gaiaMakeValid hasn't identified any offending item
to be discarded during the validation.
\sa gaiaFreeGeomColl, gaiaMakeValid
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaMakeValidDiscarded()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaMakeValidDiscarded (const void
*p_cache,
gaiaGeomCollPtr
geom);
/**
Utility function: Segmentize
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input Geometry object.
\param dist the meximum segment length.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will return a modified geometry having no segment longer than the given distance.
\n Distance computation is performed in 2d only.
\n all Points or segments shorter than 'dist' will be returned without further intervention.
\n NULL will be returned if the passed argument is invalid.
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSegmentize()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSegmentize (const void *p_cache,
gaiaGeomCollPtr geom,
double dist);
/**
Utility function: Azimuth
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param xa the X coordinate of PointA.
\param ya the Y coordinate of PointA.
\param xb the X ccordinate of PointB.
\param yb the Y coordinate of PointB.
\param azimuth on completion this variable will contain the angle in radians from
the horizontal of the vector defined by pointA and pointB.
\n Angle is computed clockwise from down-to-up: on the clock: 12=0; 3=PI/2; 6=PI; 9=3PI/2.
\return 0 on failure: any other value on success
\sa gaiaProjectedPoint
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaAzimuth (const void *p_cache, double xa,
double ya, double xb, double yb,
double *azimuth);
/**
Utility function: EllipsoidAzimuth
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param xa the X coordinate of PointA.
\param ya the Y coordinate of PointA.
\param xb the X ccordinate of PointB.
\param yb the Y coordinate of PointB.
\param a major axis of the reference spheroid.
\param b minor axis of the reference spheroid.
\param azimuth on completion this variable will contain the angle in radians from
the horizontal of the vector defined by pointA and pointB.
\n Angle is computed clockwise from down-to-up: on the clock: 12=0; 3=PI/2; 6=PI; 9=3PI/2.
\return 0 on failure: any other value on success
\sa gaiaAzimuth
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaEllipsoidAzimuth (const void *p_cache, double xa,
double ya, double xb, double yb,
double a, double b,
double *azimuth);
/**
Utility function: ProjectedPoint
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param x1 the X coordinate of the Start Point.
\param y1 the Y coordinate of the Start Point.
\param a major axis of the reference spheroid.
\param b minor axis of the reference spheroid.
\param distance a distance expressed in Meters
\param azimuth (aka bearing aka heading) expressed in radians;
on the clock: 12=0; 3=PI/2; 6=PI; 9=3PI/2.
\param x2 on completion this variable will contain the the X coordinate
of the Projected Point.
\param y2 on completion this variable will contain the the Y coordinate
of the Projected Point.
\return 0 on failure: any other value on success
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaProjectedPoint (const void *p_cache, double x1,
double y1, double a, double b,
double distance, double azimuth,
double *x2, double *y2);
/**
Utility function: GeoHash
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input geometry.
\param precision the expected precision: if <= 0 will be automatically determined.
\return NULL on failure: a null-terminated text string on success
\note you are responsible to free (before or after) any text string returned
by gaiaGeoHash()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE char *gaiaGeoHash (const void *p_cache,
gaiaGeomCollPtr geom, int precision);
/**
Utility function: AsX3D
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the input geometry.
\param srs the WKT SRS definition.
\param precision the expected precision (coord decimal digits).
\param options
\param refid the X3D namespace
\return NULL on failure: a null-terminated text string on success
\note you are responsible to free (before or after) any text string returned
by gaiaAsX3D()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE char *gaiaAsX3D (const void *p_cache,
gaiaGeomCollPtr geom, const char *srs,
int precision, int options,
const char *refid);
/**
Calculates the minimum 3D distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\param dist on completion this variable will contain the calculated distance
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance, gaiaMaxDistance, gaia3DMaxDisance
\note this function computes the 3D cartesian distance (if Z is supported)
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaia3DDistance (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist);
/**
Calculates the maximum 2D distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\param dist on completion this variable will contain the calculated distance
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance, gaia3DDistance, gaia3DMaxDistance
\note this function computes the 2D maximum cartesian distance (Z is always ignored)
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaMaxDistance (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist);
/**
Calculates the maximum 3D distance intercurring between two Geometry objects
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom1 the first Geometry object
\param geom2 the second Geometry object
\param dist on completion this variable will contain the calculated distance
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance, gaia3DDistance, gaiaMaxDistance
\note this function computes the 3D maximum cartesian distance (if Z is supported)
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaia3DMaxDistance (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist);
/**
Calculates the 2D or 3D Length for a Linestring or Multilinestring
accordingly to the dimensions of Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry object
\param length on completion this variable will contain the calculated length
\return 0 on failure: any other value on success.
\sa gaiaGeomCollDistance
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaia3dLength (const void *p_cache,
gaiaGeomCollPtr geom, double *length);
/**
Utility function: Split
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param input the input Geometry object.
\param blade the blade Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n The function supports splitting a line by point, a line by line, a polygon by line.
\sa gaiaFreeGeomColl, gaiaSplitLeft, gaiaSplitRight
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSplit()
\note gaiaSplit will return both the \b left and the \b right split halves at the same time.
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSplit (const void *p_cache,
gaiaGeomCollPtr input,
gaiaGeomCollPtr blade);
/**
Utility function: SplitLeft
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param input the input Geometry object.
\param blade the blade Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n The function supports splitting a line by point, a line by line, a polygon by line.
\sa gaiaFreeGeomColl, gaiaSplit, gaiaSplitRight
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSplitLeft()
\note gaiaSplitLeft will only return the \b left split half; NULL may be eventually
returned if empty.
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSplitLeft (const void *p_cache,
gaiaGeomCollPtr input,
gaiaGeomCollPtr blade);
/**
Utility function: SplitRight
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param input the input Geometry object.
\param blade the blade Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n The function supports splitting a line by point, a line by line, a polygon by line.
\sa gaiaFreeGeomColl, gaiaSplit, gaiaSplitLeft
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSplitRight()
\note gaiaSplitLeft will only return the \b right split half; NULL may be eventually
returned if empty.
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSplitRight (const void *p_cache,
gaiaGeomCollPtr input,
gaiaGeomCollPtr blade);
/**
Measures the total Area for a Geometry object (geodesic)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom pointer to Geometry object
\param a major axis of the reference spheroid.
\param b minor axis of the reference spheroid.
\param use_ellipsoid if TRUE will measure the Area on the Ellipsoid,
otherwise on the Sphere
\param area on completion this variable will contain the measured area
\return 0 on failure: any other value on success
\sa gaiaGeomCollLength, gaiaMeasureArea, gaiaGeomCollArea
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaGeodesicArea (const void *p_cache,
gaiaGeomCollPtr geom, double a,
double b, int use_ellipsoid,
double *area);
/**
Utility function: re-noding lines
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param input the input Geometry object.
\return the pointer to newly created Geometry object: NULL on failure.
\n The function fully nodes a set of linestrings, using the least nodes
preserving all the input ones.
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaNodeLines()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaNodeLines (const void *p_cache,
gaiaGeomCollPtr input);
/**
Utility function: subdividing Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param input the input Geometry object.
\param max_vertices the maximun number of vertices for each part in the
output geometry that will be returned.
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSubdivide()
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSubdivide (const void *p_cache,
gaiaGeomCollPtr input,
int max_vertices);
/**
Converts a native binary Geometry into a compressed TWKB Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry to be converted
\param precision_xy how much precision (decimal digits) X and Y
\param precision_z how much precision (decimal digits) Z
\param precision_m how much precision (decimal digits) M
\param with_size including sizes into the TWKB
\param with_bbox including a BBOX into the TWKB
\param twkb on succesfull completion this pointer will reference the
TWKB geometry
\param size_twkb on succesfull completion this pointer will reference
the size (in bytes) of the TWKB geometry
\return 0 on failure: any other value on success.
\sa gaiaFromTWKB
\note you are responsible to free (before or after) the TWKB geometry
created by gaiaToTWKB().
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaToTWKB (const void *p_cache,
gaiaGeomCollPtr geom,
unsigned char precision_xy,
unsigned char precision_z,
unsigned char precision_m, int with_size,
int with_bbox, unsigned char **twkb,
int *size_twkb);
/**
Converts a compressed TWKB Geometry into a native binary Geometry
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param twkb pointer to TWKB geometry
\param twkb_size size (in bytes) of the TWKB geometry
\param srid the SRID of the returned Geometry
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaToTWKB
\note you are responsible to destroy the native geometry
returned by gaiaFromTWKB().
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaFromTWKB (const void *p_cache,
const unsigned char *twkb,
int twkb_size, int srid);
/**
Converts a native binary Geometry into a GoogleMaps encoded PolyLine
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param geom the Geometry to be converted
\param precision how much precision (decimal digits)
\param encoded on succesfull completion this pointer will reference the
GoogleMaps encoded PolyLine
\param len on succesfull completion this pointer will reference
the length (in bytes) of the GoogleMaps encoded PolyLine
\return 0 on failure: any other value on success.
\sa gaiaLineFromEncodedPolyline
\note you are responsible to free (before or after) the TWKB geometry
created by gaiaToTWKB().
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE int gaiaAsEncodedPolyLine (const void *p_cache,
gaiaGeomCollPtr geom,
unsigned char precision,
char **encoded, int *len);
/**
Converts a GoogleMaps encoded PolyLine into a native binary Geometry (Linestring)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param encoded pointer to GoogleMaps encoded PolyLine
\param precision how much precision (decimal digits)
\return the pointer to newly created Geometry object: NULL on failure.
\sa gaiaAsEncodedPolyLine
\note you are responsible to destroy the native geometry
returned by gaiaFromTWKB().
\remark \b RTTOPO support required.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLineFromEncodedPolyline (const void
*p_cache,
const char
*encoded,
unsigned char
precision);
#endif /* end RTTOPO support */
/**
Utility function: DrapeLine
\param db_handle pointer to the current DB connection.
\param geom1 the first Geometry object (expected to be a 2D Linestring).
\param geom2 the second Geometry object (expected to be a 3D Linestring).
\param tolerance tolerance radius.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will return a Geometry of the Linestring type having
all points defined by geom1 and dimensions as defined by geom2.
Missing Z and/or M coords will by recovered by corresponding points
found in geom2 within the given tolerance radius.
\n both geom1 and geom2 must share the same SRID.
\sa gaiaFreeGeomColl, gaiaDrapeLineExceptions
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaDrapeLine()
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDrapeLine (sqlite3 * db_handle,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2,
double tolerance);
/**
Utility function: DrapeLineExceptions
\param db_handle pointer to the current DB connection.
\param geom1 the first Geometry object (expected to be a 2D Linestring).
\param geom2 the second Geometry object (expected to be a 3D Linestring).
\param tolerance tolerance radius.
\param interpolated boolean: if TRUE all Vertices for whom Z (and/or M)
values had been succesfully interpolated will be considered as valid.
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will return a Geometry of the MultiPoint type containing
all Vertices from geom1 lacking a corresponding Vertex in geom2, thus
leading to dubious Z and/or M coords.
\n both geom1 and geom2 must share the same SRID.
\sa gaiaFreeGeomColl, gaiaDrapeLine
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaDrapeLine()
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDrapeLineExceptions (sqlite3 *
db_handle,
gaiaGeomCollPtr
geom1,
gaiaGeomCollPtr
geom2,
double tolerance,
int interpolated);
#endif /* end including GEOS */
/**
Utility function: SnapToGrid
\param geom the input Geometry object.
\param origin_x the X ccordinate identifying the Grid Origin.
\param origin_y the Y coordinate identifiying the Grid Origin.
\param origin_z the Z ccordinate identifying the Grid Origin.
\param origin_m the M coordinate identifiying the Grid Origin.
\param size_x Grid cell size (X axis).
\param size_y Grid cell size (Y axis).
\param size_z Grid cell size (Z axis).
\param size_m Grid cell size (M axis).
\return the pointer to newly created Geometry object: NULL on failure.
\n this function will return a modified geometry having all points snapped to a regular Grid
defined by its origin and cell size.
\n Consecutive points falling on the same cell will be removed, eventually returning NULL if
\n output points are not enough to define a geometry of the given type.
\n Collapsed geometries in a collection are stripped from it.
\n Specify 0 as size for any dimension you don't want to snap to a grid.
\n NULL will be returned if the passed argument is invalid.
\sa gaiaFreeGeomColl
\note you are responsible to destroy (before or after) any allocated Geometry,
this including any Geometry returned by gaiaSnapToGrid()
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSnapToGrid (gaiaGeomCollPtr geom,
double origin_x,
double origin_y,
double origin_z,
double origin_m,
double size_x,
double size_y,
double size_z,
double size_m);
#ifdef __cplusplus
}
#endif
#endif /* _GG_ADVANCED_H */
libspatialite-5.1.0/src/headers/spatialite/gg_xml.h 0000644 0001750 0001750 00000071223 14463127014 017262 0000000 0000000 /*
gg_xml.h -- Gaia common support for XML documents
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_xml.h
Geometry handling functions: XML document
*/
#ifndef _GG_XML_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_XML_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constant values for XmlBLOB */
/** XmlBLOB internal marker: START */
#define GAIA_XML_START 0x00
/** XmlBLOB internal marker: END */
#define GAIA_XML_END 0xDD
/** XmlBLOB internal marker: HEADER */
#define GAIA_XML_HEADER 0xAC
/** XmlBLOB internal marker: LEGACY HEADER */
#define GAIA_XML_LEGACY_HEADER 0xAB
/** XmlBLOB internal marker: SCHEMA */
#define GAIA_XML_SCHEMA 0xBA
/** XmlBLOB internal marker: FILEID */
#define GAIA_XML_FILEID 0xCA
/** XmlBLOB internal marker: PARENTID */
#define GAIA_XML_PARENTID 0xDA
/** XmlBLOB internal marker: TITLE */
#define GAIA_XML_NAME 0xDE
/** XmlBLOB internal marker: TITLE */
#define GAIA_XML_TITLE 0xDB
/** XmlBLOB internal marker: ABSTRACT */
#define GAIA_XML_ABSTRACT 0xDC
/** XmlBLOB internal marker: GEOMETRY */
#define GAIA_XML_GEOMETRY 0xDD
/** XmlBLOB internal marker: CRC32 */
#define GAIA_XML_CRC32 0xBC
/** XmlBLOB internal marker: PAYLOAD */
#define GAIA_XML_PAYLOAD 0xCB
/* bitmasks for XmlBLOB-FLAG */
/** XmlBLOB FLAG - LITTLE_ENDIAN bitmask */
#define GAIA_XML_LITTLE_ENDIAN 0x01
/** XmlBLOB FLAG - COMPRESSED bitmask */
#define GAIA_XML_COMPRESSED 0x02
/** XmlBLOB FLAG - VALIDATED bitmask */
#define GAIA_XML_VALIDATED 0x04
/** XmlBLOB FLAG - ISO METADATA bitmask */
#define GAIA_XML_ISO_METADATA 0x80
/** XmlBLOB FLAG - SLDSE VECTOR STYLE bitmask */
#define GAIA_XML_SLD_SE_RASTER_STYLE 0x10
/** XmlBLOB FLAG - SLDSE VECTOR STYLE bitmask */
#define GAIA_XML_SLD_SE_VECTOR_STYLE 0x40
/** XmlBLOB FLAG - SLD STYLE bitmask */
#define GAIA_XML_SLD_STYLE 0x48
/** XmlBLOB FLAG - SVG bitmask */
#define GAIA_XML_SVG 0x20
/** XmlBLOB FLAG - GPX bitmask */
#define GAIA_XML_GPX 0x08
/** XmlBLOB FLAG - MapConfig bitmask */
#define GAIA_XML_MAP_CONFIG 0x88
/* function prototypes */
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#ifdef ENABLE_LIBXML2 /* LIBXML2 enabled: supporting XML documents */
#endif
/**
return the LIBXML2 version string
\return a text string identifying the current LIBXML2 version
\note the version string corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE char *gaia_libxml2_version (void);
/**
Creates an XmlBLOB buffer
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param xml pointer to the XML document (XmlBLOB payload).
\param xml_len lenght of the XML document (in bytes).
\param compressed if TRUE the returned XmlBLOB will be zip-compressed.
\param schemaURI if not NULL the XML document will be assumed to be valid
only if it successfully passes a formal Schema valitadion.
\param result on completion will containt a pointer to XmlBLOB:
NULL on failure.
\param size on completion this variable will contain the XmlBLOB's size (in bytes)
\param parsing_errors on completion this variable will contain all error/warning
messages emitted during the XML Parsing step. Can be set to NULL so to ignore any message.
\param schema_validation_errors on completion this variable will contain all error/warning
messages emitted during the XML Schema Validation step. Can be set to NULL so to ignore any message.
\sa gaiaXmlFromBlob, gaiaXmlTextFromBlob, gaiaXmlBlobGetLastParseError,
gaiaXmlBlobGetLastValidateError
\note the XmlBLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaXmlToBlob (const void *p_cache,
const unsigned char *xml, int xml_len,
int compressed, const char *schemaURI,
unsigned char **result, int *size,
char **parsing_errors,
char **schema_validation_errors);
/**
Extract an XMLDocument from within an XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\param indent if a negative value is passed the XMLDocument will
be extracted exactly as it was when loaded. Otherwise it will be
properly formatted using the required intenting (max. 8); ZERO
means that the whole XML Document will consist of a single line.
\return the pointer to the newly created XMLDocument buffer: NULL on failure
\sa gaiaXmlToBlob, gaiaXmlFromBlob
\note the returned XMLDocument will always be encoded as UTF-8 (irrespectively
from the internal encoding declaration), so to allow any further processing as
SQLite TEXT.
\note the XMLDocument buffer corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlTextFromBlob (const unsigned char *blob,
int size, int indent);
/**
Extract an XMLDocument from within an XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\param indent if a negative value is passed the XMLDocument will
be extracted exactly as it was when loaded. Otherwise it will be
properly formatted using the required intenting (max. 8); ZERO
means that the whole XML Document will consist of a single line.
\param result pointer to the memory buffer containing the XML Document
\param res_size dimension (in bytes) of the XML Document memory buffer
(both values will be passed back after successful completion).
\sa gaiaXmlToBlob, gaiaXmlTextFromBlob
\note the returned XMLDocument will always respect the internal encoding declaration,
and may not support any further processing as SQLite TEXT if it's not UTF-8.
\note the XMLDocument buffer corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE void gaiaXmlFromBlob (const unsigned char *blob,
int size, int indent,
unsigned char **result,
int *res_size);
/**
Checks if a BLOB actually is a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE
\sa gaiaIsCompressedXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsIsoMetadataXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsValidXmlBlob (const unsigned char *blob,
int size);
/**
Checks if a valid XmlBLOB buffer is compressed or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsIsoMetadataXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsCompressedXmlBlob (const unsigned char *blob,
int size);
/**
Checks if a valid XmlBLOB buffer does contain an ISO Metadata or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsIsoMetadataXmlBlob (const unsigned char *blob,
int size);
/**
Checks if a valid XmlBLOB buffer does contain an SLD/SE Style or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB of the
Vector type; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsSldSeVectorStyleXmlBlob (const unsigned char
*blob, int size);
/**
Checks if a valid XmlBLOB buffer does contain an SLD/SE Style or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB of the
Raster type; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsSldSeRasterStyleXmlBlob (const unsigned char
*blob, int size);
/**
Checks if a valid XmlBLOB buffer does contain an SLD Style or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB of the
SLD type; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldSeRasterXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsSldStyleXmlBlob (const unsigned char
*blob, int size);
/**
Checks if a valid XmlBLOB buffer does contain a MapConfig or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB of the
MapConfig type; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldSeRasterXmlBlob,
gaiaIsSvgXmlBlob, gaiaIsGpxXmlBlob, gaiaIsSldStyleXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsMapConfigXmlBlob (const unsigned char
*blob, int size);
/**
Checks if a valid XmlBLOB buffer does contain an SVG Symbol or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsGpxXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsSvgXmlBlob (const unsigned char *blob, int size);
/**
Checks if a valid XmlBLOB buffer does contain a GPX document or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB; -1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSchemaValidatedXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSvgXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsGpxXmlBlob (const unsigned char *blob, int size);
/**
Return another XmlBLOB buffer compressed / uncompressed
\param blob pointer to the input XmlBLOB buffer.
\param in_size input XmlBLOB's size (in bytes).
\param compressed if TRUE the returned XmlBLOB will be zip-compressed.
\param result on completion will containt a pointer to the output XmlBLOB:
NULL on failure.
\param out_size on completion this variable will contain the output XmlBLOB's size (in bytes)
\sa gaiaXmlToBlob, gaiaIsCompressedXmlBlob
\note the XmlBLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE void gaiaXmlBlobCompression (const unsigned char *blob,
int in_size, int compressed,
unsigned char **result,
int *out_size);
/**
Checks if a valid XmlBLOB buffer has successfully passed a formal Schema validation or not
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return TRUE or FALSE if the BLOB actually is a valid XmlBLOB but not schema-validated;
-1 in any other case.
\sa gaiaIsValidXmlBlob, gaiaIsSvgXmlBlob,
gaiaIsCompressedXmlBlob, gaiaIsIsoMetadataXmlBlob,
gaiaIsSldSeVectorStyleXmlBlob, gaiaIsSldSeRasterStyleXmlBlob,
gaiaIsSldStyleXmlBlob, gaiaIsMapConfigXmlBlob
*/
GAIAGEO_DECLARE int gaiaIsSchemaValidatedXmlBlob (const unsigned char
*blob, int size);
/**
Return the XMLDocument size (in bytes) from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the XMLDocument size (in bytes) for any valid XmlBLOB;
-1 if the BLOB isn't a valid XmlBLOB.
*/
GAIAGEO_DECLARE int gaiaXmlBlobGetDocumentSize (const unsigned char *blob,
int size);
/**
Return the SchemaURI from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the SchemaURI for any valid XmlBLOB containing a SchemaURI;
NULL in any other case.
\sa gaiaXmlGetInternalSchemaURI
\note the returned SchemaURI corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetSchemaURI (const unsigned char
*blob, int size);
/**
Return the Internal SchemaURI from a valid XmlDocument
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param xml pointer to the XML document
\param xml_len lenght of the XML document (in bytes).
\return the SchemaURI eventually defined within a valid XMLDocument;
NULL if the XMLDocument is invalid, or if it doesn't contain any SchemaURI.
\sa gaiaXmlBlobGetSchemaURI
\note the returned SchemaURI corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlGetInternalSchemaURI (const void *p_cache,
const unsigned char
*xml, int xml_len);
/**
Return the FileIdentifier from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the FileIdentifier for any valid XmlBLOB containing a FileIdentifier;
NULL in any other case.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobSetFileId, gaiaXmlBlobAddFileId
\note the returned FileIdentifier corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetFileId (const unsigned char
*blob, int size);
/**
Return the ParentIdentifier from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the ParentIdentifier for any valid XmlBLOB containing a ParentIdentifier;
NULL in any other case.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobSetParentId, gaiaXmlBlobAddParentId
\note the returned ParentIdentifier corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetParentId (const unsigned char
*blob, int size);
/**
Return a new XmlBLOB (ISO Metadata) by replacing the FileId value
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param blob pointer to the input XmlBLOB buffer.
\param size input XmlBLOB's size (in bytes).
\param identifier the new FileId value to be set.
\param new_blob on completion will contain a pointer to the output XmlBLOB buffer.
\param new_size on completion will containg the output XmlBlob's size (in bytes).
\return TRUE for success; FALSE for any failure cause.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobGetFileId, gaiaXmlBlobAddFileId
\note the output XmlBLOB corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE int gaiaXmlBlobSetFileId (const void *p_cache,
const unsigned char *blob,
int size,
const char *identifier,
unsigned char **new_blob,
int *new_size);
/**
Return a new XmlBLOB (ISO Metadata) by replacing the ParentId value
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param blob pointer to the inputXmlBLOB buffer.
\param size input XmlBLOB's size (in bytes).
\param identifier the new ParentId value to be set.
\param new_blob on completion will contain a pointer to the output XmlBLOB buffer.
\param new_size on completion will containg the output XmlBlob's size (in bytes).
\return TRUE for success; FALSE for any failure cause.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobGetParentId, gaiaXmlBlobAddParentId
\note the returned XmlBLOB corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE int gaiaXmlBlobSetParentId (const void *p_cache,
const unsigned char *blob,
int size,
const char *identifier,
unsigned char **new_blob,
int *new_size);
/**
Return a new XmlBLOB (ISO Metadata) by inserting a FileId value
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param blob pointer to the input XmlBLOB buffer.
\param size input XmlBLOB's size (in bytes).
\param identifier the new FileId value to be inserted.
\param ns_id prefix corresponding to FileIdentifier NameSpace (may be NULL)
\param uri_id URI corresponding to the FileIdentifier NameSpace (may be NULL)
\param ns_charstr prefix corresponding to CharacterString NameSpace (may be NULL)
\param uri_charstr URI corresponding to CharacterString NameSpace (may be NULL)
\param new_blob on completion will contain a pointer to the output XmlBLOB buffer.
\param new_size on completion will containg the output XmlBlob's size (in bytes).
\return TRUE for success; FALSE for any failure cause.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobGetFileId, gaiaXmlBlobSetFileId
\note the output XmlBLOB corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE int gaiaXmlBlobAddFileId (const void *p_cache,
const unsigned char *blob,
int size,
const char *identifier,
const char *ns_id,
const char *uri_id,
const char *ns_charstr,
const char *uri_charstr,
unsigned char **new_blob,
int *new_size);
/**
Return a new XmlBLOB (ISO Metadata) by inserting a ParentId value
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param blob pointer to the inputXmlBLOB buffer.
\param size input XmlBLOB's size (in bytes).
\param identifier the new ParentId value to be inserted.
\param ns_id prefix corresponding to FileIdentifier NameSpace (may be NULL)
\param uri_id URI corresponding to the FileIdentifier NameSpace (may be NULL)
\param ns_charstr prefix corresponding to CharacterString NameSpace (may be NULL)
\param uri_charstr URI corresponding to CharacterString NameSpace (may be NULL)
\param new_blob on completion will contain a pointer to the output XmlBLOB buffer.
\param new_size on completion will containg the output XmlBlob's size (in bytes).
\return TRUE for success; FALSE for any failure cause.
\sa gaiaIsIsoMetadataXmlBlob, gaiaXmlBlobGetParentId, gaiaXmlBlobSetParentId
\note the returned XmlBLOB corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE int gaiaXmlBlobAddParentId (const void *p_cache,
const unsigned char *blob,
int size,
const char *identifier,
const char *ns_id,
const char *uri_id,
const char *ns_charstr,
const char *uri_charstr,
unsigned char **new_blob,
int *new_size);
/**
Return the Name from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the Name for any valid XmlBLOB containing a Name;
NULL in any other case.
\sa gaiaIsIsoMetadataXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob
\note the returned Name corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetName (const unsigned char
*blob, int size);
/**
Return the Title from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the Title for any valid XmlBLOB containing a Title;
NULL in any other case.
\sa gaiaIsIsoMetadataXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob
\note the returned Title corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetTitle (const unsigned char
*blob, int size);
/**
Return the Abstract from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the Abstract for any valid XmlBLOB containing an Abstract;
NULL in any other case.
\sa gaiaIsIsoMetadataXmlBlob, gaiaIsSldSeVectorStyleXmlBlob,
gaiaIsSldSeRasterStyleXmlBlob, gaiaIsSldStyleXmlBlob
\note the returned Abstract corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetAbstract (const unsigned char
*blob, int size);
/**
Return the Geometry buffer from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\param blob_geom on completion this variable will contain
a pointer to the returned Geometry buffer (NULL if no Geometry
was defined within the XmlBLOB)
\param blob_size on completion this variable will contain
the size (in bytes) of the returned Geometry buffer
\sa gaiaIsIsoMetadataXmlBlob
\note the returned Geometry buffer corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE void gaiaXmlBlobGetGeometry (const unsigned char
*blob, int size,
unsigned char **blob_geom,
int *blob_size);
/**
Return a MultiLinestring Geometry from a valid GPX XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\param db_handle handle to the current SQLite connection
\return a Geometry of the MultiLinestring type, or NULL
\sa gaiaIsIsoMetadataXmlBlob
\note the returned Geometry corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaXmlBlobMLineFromGPX (const unsigned
char *blob,
int size,
sqlite3 *
db_handle);
/**
Return the Charset Encoding from a valid XmlBLOB buffer
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\return the Charset Encoding for any valid XmlBLOB explicitly defining an Encoding;
NULL in any other case.
\note the returned Encoding corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetEncoding (const unsigned char
*blob, int size);
/**
Return the most recent XML Parse error/warning (if any)
\param ptr a memory pointer returned by spatialite_alloc_connection()
\return the most recent XML Parse error/warning message (if any);
NULL in any other case.
\sa gaiaXmlBlobGetLastValidateError, gaiaIsValidXPathExpression,
gaiaXmlBlobGetLastXPathError
\note the returned error/warning message corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetLastParseError (const void *p_cache);
/**
Return the most recent XML Validate error/warning (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the most recent XML Validate error/warning message (if any);
NULL in any other case.
\sa gaiaXmlBlobGetLastParseError, gaiaIsValidXPathExpression,
gaiaXmlBlobGetLastXPathError
\note the returned error/warning message corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetLastValidateError (const void *p_cache);
/**
Checks if a Text string could be a valid XPathExpression
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param xpath_expr pointer to the XPathExpression to be checked.
\return TRUE or FALSE if the Text string actually is a valid XPathExpression;
-1 in any other case.
\sa gaiaXmlBlobGetLastXPathError
*/
GAIAGEO_DECLARE int gaiaIsValidXPathExpression (const void *p_cache,
const char *xpath_expr);
/**
Return the most recent XPath error/warning (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the most recent XPath error/warning message (if any);
NULL in any other case.
\sa gaiaXmlBlobGetLastParseError, gaiaXmlBlobGetLastValidateError,
gaiaIsValidXPathExpression
\note the returned error/warning message corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
*/
GAIAGEO_DECLARE char *gaiaXmlBlobGetLastXPathError (const void *p_cache);
/**
Load an external XML Document
\param path_or_url pointer to the external XML Document (could be a pathname or an URL).
\param result on completion will containt a pointer to a BLOB:
NULL on failure.
\param size on completion this variable will contain the BLOB's size (in bytes).
\param parsing_errors on completion this variable will contain all error/warning
messages emitted during the XML Parsing step. Can be set to NULL so to ignore any message.
\sa gaiaXmlFromBlob, gaiaXmlStore
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE int gaiaXmlLoad (const void *p_cache,
const char *path_or_url,
unsigned char **result, int *size,
char **parsing_errors);
/**
Stores an external XML Document
\param blob pointer to the XmlBLOB buffer.
\param size XmlBLOB's size (in bytes).
\param path pathname of the export file
\param indent if a negative value is passed the XMLDocument will
be extracted exactly as it was when loaded. Otherwise it will be
properly formatted using the required intenting (max. 8); ZERO
means that the whole XML Document will consist of a single line.
\sa gaiaXmlToBlob, gaiaXmlTextFromBlob
\note the returned XMLDocument will always respect the internal encoding declaration,
and may not support any further processing as SQLite TEXT if it's not UTF-8.
\note the XMLDocument buffer corresponds to dynamically allocated memory:
so you are responsible to free() it before or after.
\sa gaiaXmlFromBlob, gaiaXmlLoad
\note the BLOB buffer corresponds to dynamically allocated memory:
so you are responsible to free() it [unless SQLite will take care
of memory cleanup via buffer binding].
*/
GAIAGEO_DECLARE int gaiaXmlStore (const unsigned char *blob, int size,
const char *path, int indent);
#endif /* end LIBXML2: supporting XML documents */
#ifdef __cplusplus
}
#endif
#endif /* _GG_XML_H */
libspatialite-5.1.0/src/headers/spatialite/gg_wfs.h 0000644 0001750 0001750 00000052131 14463127014 017256 0000000 0000000 /*
gg_wfs.h -- Gaia common support for WFS
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_wfs.h
WFS support
*/
#ifndef _GG_WFS_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_WFS_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct gaia_wfs_catalog gaiaWFScatalog;
typedef gaiaWFScatalog *gaiaWFScatalogPtr;
typedef struct gaia_wfs_item gaiaWFSitem;
typedef gaiaWFSitem *gaiaWFSitemPtr;
typedef struct gaia_wfs_schema gaiaWFSschema;
typedef gaiaWFSschema *gaiaWFSschemaPtr;
typedef struct gaia_wfs_column gaiaWFScolumn;
typedef gaiaWFScolumn *gaiaWFScolumnPtr;
/**
Loads data from some WFS source
\param sqlite handle to current DB connection
\param path_or_url pointer to some WFS-GetFeature XML Document (could be a pathname or an URL).
\param alt_describe_uri an alternative URI for DescribeFeatureType to be used
if no one is found within the XML document returned by GetFeature.
\param layer_name the name of the WFS layer.
\param swap_axes if TRUE the X and Y axes will be swapped
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param rows on completion will contain the total number of actually imported rows
\param err_msg on completion will contain an error message (if any)
\param progress_callback pointer to a callback function to be invoked immediately
after processing each WFS page (could be NULL)
\param callback_ptr an arbitrary pointer (to be passed as the second argument
by the callback function).
\sa create_wfs_catalog, load_from_wfs_paged, reset_wfs_http_connection
\return 0 on failure, any other value on success
\note an eventual error message returned via err_msg requires to be deallocated
by invoking free()
\n please note: this one simply is a convenience method, and exactly corresponds
to load_from_wfs_paged() setting a negative page size.
*/
SPATIALITE_DECLARE int load_from_wfs (sqlite3 * sqlite,
const char *path_or_url,
const char *alt_describe_uri,
const char *layer_name,
int swap_axes, const char *table,
const char *pk_column_name,
int spatial_index, int *rows,
char **err_msg,
void (*progress_callback) (int,
void *),
void *callback_ptr);
/**
Loads data from some WFS source (using WFS paging)
\param sqlite handle to current DB connection
\param path_or_url pointer to some WFS-GetFeature XML Document (could be a pathname or an URL).
\param alt_describe_uri an alternative URI for DescribeFeatureType to be used
if no one is found within the XML document returned by GetFeature.
\param layer_name the name of the WFS layer.
\param swap_axes if TRUE the X and Y axes will be swapped
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param page_size max number of features for each single WFS call; if zero or
negative a single monolithic page is assumed (i.e. paging will not be applied).
\param rows on completion will contain the total number of actually imported rows
\param err_msg on completion will contain an error message (if any)
\param progress_callback pointer to a callback function to be invoked immediately
after processing each WFS page (could be NULL)
\param callback_ptr an arbitrary pointer (to be passed as the second argument
by the callback function).
\sa create_wfs_catalog, load_from_wfs, reset_wfs_http_connection,
load_from_wfs_paged_ex
\return 0 on failure, any other value on success
\note an eventual error message returned via err_msg requires to be deallocated
by invoking free()
\note the progress_callback function must have this signature:
\b void \b myfunct(\b int \b count, \b void \b *ptr);
\n and will cyclically report how many features have been processed since the initial call start.
\note this function is now deprecated and simply defaults to a call to
load_from_wfs_paged_ex assuming WFS version 1.1.0
*/
SPATIALITE_DECLARE int load_from_wfs_paged (sqlite3 * sqlite,
const char *path_or_url,
const char *alt_describe_uri,
const char *layer_name,
int swap_axes,
const char *table,
const char *pk_column_name,
int spatial_index,
int page_size, int *rows,
char **err_msg,
void (*progress_callback)
(int, void *),
void *callback_ptr);
/**
Loads data from some WFS source (using WFS paging) - Extended
\param sqlite handle to current DB connection
\param wfs_version one of "1.0.0", "1.1.0", "2.0.0" or "2.0.2"
\param path_or_url pointer to some WFS-GetFeature XML Document (could be a pathname or an URL).
\param alt_describe_uri an alternative URI for DescribeFeatureType to be used
if no one is found within the XML document returned by GetFeature.
\param layer_name the name of the WFS layer.
\param swap_axes if TRUE the X and Y axes will be swapped
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param page_size max number of features for each single WFS call; if zero or
negative a single monolithic page is assumed (i.e. paging will not be applied).
\param rows on completion will contain the total number of actually imported rows
\param err_msg on completion will contain an error message (if any)
\param progress_callback pointer to a callback function to be invoked immediately
after processing each WFS page (could be NULL)
\param callback_ptr an arbitrary pointer (to be passed as the second argument
by the callback function).
\sa create_wfs_catalog, load_from_wfs, reset_wfs_http_connection
\return 0 on failure, any other value on success
\note an eventual error message returned via err_msg requires to be deallocated
by invoking free()
\note the progress_callback function must have this signature:
\b void \b myfunct(\b int \b count, \b void \b *ptr);
\n and will cyclically report how many features have been processed since the initial call start.
*/
SPATIALITE_DECLARE int load_from_wfs_paged_ex (sqlite3 * sqlite,
const char *wfs_version,
const char *path_or_url,
const char *alt_describe_uri,
const char *layer_name,
int swap_axes,
const char *table,
const char *pk_column_name,
int spatial_index,
int page_size, int *rows,
char **err_msg,
void (*progress_callback)
(int, void *),
void *callback_ptr);
/**
Creates a Catalog for some WFS service
\param path_or_url pointer to some WFS-GetCapabilities XML Document (could be a pathname or an URL).
\param err_msg on completion will contain an error message (if any)
\return the pointer to the corresponding WFS-Catalog object: NULL on failure
\sa destroy_wfs_catalog, get_wfs_catalog_count, get_wfs_catalog_item, load_from_wfs,
reset_wfs_http_connection, get_wfs_version
\note an eventual error message returned via err_msg requires to be deallocated
by invoking free().\n
you are responsible to destroy (before or after) any WFS-Catalog returned by create_wfs_catalog().
*/
SPATIALITE_DECLARE gaiaWFScatalogPtr create_wfs_catalog (const char
*path_or_url,
char **err_msg);
/**
Destroys a WFS-Catalog object freeing any allocated resource
\param handle the pointer to a valid WFS-Catalog returned by a previous call
to create_wfs_catalog()
\sa create_wfs_catalog
*/
SPATIALITE_DECLARE void destroy_wfs_catalog (gaiaWFScatalogPtr handle);
/**
Return the WFS-Version string as reported by GetCapabilities
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the WFS Version string: NULL is undefined
\sa create_wfs_catalog
*/
SPATIALITE_DECLARE const char *get_wfs_version (gaiaWFScatalogPtr handle);
/**
Return the base URL for any WFS-GetFeature call
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the base URL for any WFS-GetFeature call: NULL is undefined
\sa create_wfs_catalog, get_wfs_base_describe_url, get_wfs_request_url
*/
SPATIALITE_DECLARE const char *get_wfs_base_request_url (gaiaWFScatalogPtr
handle);
/**
Return the base URL for any WFS-DescribeFeatureType call
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the base URL for any WFS-DescribeFeatureType call: NULL is undefined
\sa create_wfs_catalog, get_wfs_base_request_url, get_wfs_describe_url
*/
SPATIALITE_DECLARE const char
*get_wfs_base_describe_url (gaiaWFScatalogPtr handle);
/**
Return a GetFeature URL (GET)
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\param name the NAME uniquely identifying the required WFS layer.
\param version could be "1.0.0" or "1.1.0"; if NULL or invalid "1.1.0"
will be assumed.
\param srid the preferred SRS to be used for WFS geometries; if negative
or mismatching will be simply ignored.
\param max_features the WFS MAXFEATURES argument; any negative or zero
value will be ignored.
\return the GetFeature URL: NULL if any error is found.
\sa get_wfs_base_request_url, get_wfs_describe_url
\note you are responsible to destroy (before or after) any allocated
memory returned by get_wfs_request_url().
*/
SPATIALITE_DECLARE char *get_wfs_request_url (gaiaWFScatalogPtr handle,
const char *name,
const char *version,
int srid, int max_features);
/**
Return a DescribeFeatureType URL (GET)
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\param name the NAME uniquely identifying the required WFS layer.
\param version could be "1.0.0" or "1.1.0"; if NULL or invalid "1.1.0"
will be assumed.
\return the DescribeFeatureType URL: NULL if any error is found.
\sa get_wfs_base_describe_url, get_wfs_request_url
\note you are responsible to destroy (before or after) any allocated
memory returned by get_wfs_describe_url().
*/
SPATIALITE_DECLARE char *get_wfs_describe_url (gaiaWFScatalogPtr handle,
const char *name,
const char *version);
/**
Return the total count of items (aka Layers) defined within a WFS-Catalog object
\param handle the pointer to a valid WFS-Catalog returned by a previous call
to create_wfs_catalog()
\return the total count of items (aka Layers) defined within a WFS-Catalog object:
a negative number if the WFS-Catalog isn't valid
\sa create_wfs_catalog, get_wfs_catalog_item
*/
SPATIALITE_DECLARE int get_wfs_catalog_count (gaiaWFScatalogPtr handle);
/**
Return the pointer to some specific Layer defined within a WFS-Catalog object
\param handle the pointer to a valid WFS-Catalog returned by a previous call
to create_wfs_catalog()
\param index the relative index identifying the required WFS-Layer (the first
Item in the WFS-Catalaog object has index ZERO).
\return the pointer to the required WFS-Layer object: NULL if the passed index
isn't valid
\sa create_wfs_catalog, get_wfs_catalog_count, get_wfs_item_name, get_wfs_item_title,
get_wfs_item_abstract, get_wfs_layer_srid_count, get_wfs_layer_srid,
get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE gaiaWFSitemPtr get_wfs_catalog_item (gaiaWFScatalogPtr
handle, int index);
/**
Return the name corresponding to some WFS-Item (aka Layer) object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the name corresponding to the WFS-Layer object
\sa get_wfs_layer_title, get_wfs_layer_abstract, get_wfs_layer_srid_count, get_wfs_layer_srid,
get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE const char *get_wfs_item_name (gaiaWFSitemPtr handle);
/**
Return the title corresponding to some WFS-Item (aka Layer) object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the title corresponding to the WFS-Layer object
\sa get_wfs_item_name, get_wfs_item_abstract, get_wfs_layer_srid_count, get_wfs_layer_srid,
get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE const char *get_wfs_item_title (gaiaWFSitemPtr handle);
/**
Return the abstract corresponding to some WFS-Item (aka Layer) object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the abstract corresponding to the WFS-Layer object
\sa get_wfs_item_name, get_wfs_item_title, get_wfs_layer_srid_count, get_wfs_layer_srid,
get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE const char *get_wfs_item_abstract (gaiaWFSitemPtr
handle);
/**
Return the total count of SRIDs supported by a WFS-Item object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the total count of SRIDs supported by a WFS-Item object:
a negative number if the WFS-Item isn't valid
\sa get_wfs_item_name, get_wfs_item_title, get_wfs_item_abstract,
get_wfs_layer_srid, get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE int get_wfs_layer_srid_count (gaiaWFSitemPtr handle);
/**
Return one of the SRIDs supported by a WFS-Item object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\param index the relative index identifying the required SRID (the first
SRID value supported by a WFS-Item object has index ZERO).
\return the SRID-value: a negative number if the required SRID-value isn't defined.
\sa get_wfs_item_name, get_wfs_item_title, get_wfs_item_abstract,
get_wfs_layer_srid_count, get_wfs_keyword_count, get_wfs_keyword
*/
SPATIALITE_DECLARE int get_wfs_layer_srid (gaiaWFSitemPtr handle,
int index);
/**
Return the total count of Keywords associated to a WFS-Item object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\return the total count of Keyword associated to a WFS-Item object:
a negative number if the WFS-Item isn't valid
\sa get_wfs_item_name, get_wfs_item_title, get_wfs_item_abstract,
get_wfs_layer_srid_count, get_wfs_layer_srid, get_wfs_layer_keyword
*/
SPATIALITE_DECLARE int get_wfs_keyword_count (gaiaWFSitemPtr handle);
/**
Return one of the Keywords supported by a WFS-Item object
\param handle the pointer to a valid WFS-Item returned by a previous call
to get_wfs_catalog_item().
\param index the relative index identifying the required Keyword (the first
Keyword associated to a WFS-Item object has index ZERO).
\return the Keyword value: NULL if the required Keyword isn't defined.
\sa get_wfs_item_name, get_wfs_item_title, get_wfs_item_abstract,
get_wfs_layer_srid_count, get_wfs_layer_srid, get_wfs_layer_keyword
*/
SPATIALITE_DECLARE const char *get_wfs_keyword (gaiaWFSitemPtr handle,
int index);
/**
Creates a Schema representing some WFS Layer
\param path_or_url pointer to some WFS-DescribeFeatureType XML Document (could be a pathname or an URL).
\param err_msg on completion will contain an error message (if any)
\return the pointer to the corresponding WFS-Schema object: NULL on failure
\sa destroy_wfs_schema,get_wfs_schema_column_count, get_wfs_schema_column_info,
get_wfs_schema_geometry_info
\note an eventual error message returned via err_msg requires to be deallocated
by invoking free().\n
you are responsible to destroy (before or after) any WFS-Schema returned by create_wfs_schema().
*/
SPATIALITE_DECLARE gaiaWFSschemaPtr create_wfs_schema (const char
*path_or_url,
const char
*layer_name,
char **err_msg);
/**
Destroys a WFS-schema object freeing any allocated resource
\param handle the pointer to a valid WFS-Catalog returned by a previous call
to create_wfs_schema()
\sa create_wfs_schema
*/
SPATIALITE_DECLARE void destroy_wfs_schema (gaiaWFSschemaPtr handle);
/**
Return the infos describing some WFS-GeometryColumn object
\param handle the pointer to a valid WFS-Schema returned by a previous call
to create_wfs_schema().
\param name on completion will contain a pointer to the GeometryColumn name
\param type on completion will contain the GeometryType set for the Column;
could be one of GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON, GAIA_MULTIPOINT,
GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON or GAIA_GEOMETRYCOLLECTION
\param srid on completion will contain the SRID-value set for the GeometryColumn
\param dims on completion will contain the dimensions (2 or 3) set
for the GeometryColumn
\param nullable on completion will contain a Boolean value; if TRUE
the Column may contain NULL-values.
\return TRUE on success, FALSE if any error is encountered or if
the WFS-Schema hasn't any Geometry-Column defined.
\sa create_wfs_schema, get_wfs_schema_column_count, get_wfs_schema_column,
get_wfs_schema_column_info
*/
SPATIALITE_DECLARE int get_wfs_schema_geometry_info (gaiaWFSschemaPtr
handle,
const char **name,
int *type, int *srid,
int *dims,
int *nullable);
/**
Return the total count of items (aka Columns) defined within a WFS-Schema object
\param handle the pointer to a valid WFS-Schema returned by a previous call
to create_wfs_schema()
\return the total count of items (aka Columns) defined within a WFS-Schema object:
a negative number if the WFS-Schema isn't valid
\sa create_wfs_schema, get_wfs_schema_geometry_info,
get_wfs_schema_column, get_wfs_schema_column_info
*/
SPATIALITE_DECLARE int get_wfs_schema_column_count (gaiaWFSschemaPtr
handle);
/**
Return the pointer to some specific Column defined within a WFS-Schema object
\param handle the pointer to a valid WFS-Schema returned by a previous call
to create_wfs_schema()
\param index the relative index identifying the required WFS-Column (the first
Item in the WFS-Schema object has index ZERO).
\return the pointer to the required WFS-Column object: NULL if the passed index
isn't valid
\sa create_wfs_schema, get_wfs_schema_geometry_info,
get_wfs_schema_column_count, get_wfs_schema_column_info
*/
SPATIALITE_DECLARE gaiaWFScolumnPtr
get_wfs_schema_column (gaiaWFSschemaPtr handle, int index);
/**
Return the infos describing some WFS-Column object
\param handle the pointer to a valid WFS-Column returned by a previous call
to get_wfs_schema_column().
\param name on completion will contain a pointer to the Column name
\param type on completion will contain the datatype set for the Column;
could be one of SQLITE_TEXT, SQLITE_INTEGER or SQLITE_FLOAT
\param nullable on completion will contain a Boolean value; if TRUE
the Column may contain NULL-values.
\return TRUE on success, FALSE if any error is encountered
\sa get_wfs_schema_column, get_wfs_schema_geometry_info
*/
SPATIALITE_DECLARE int get_wfs_schema_column_info (gaiaWFScolumnPtr
handle,
const char **name,
int *type,
int *nullable);
/**
Resets the libxml2 "nano HTTP": useful when changing the HTTP_PROXY settings
\sa create_wfs_catalog, load_from_wfs, load_from_wfs_paged
*/
SPATIALITE_DECLARE void reset_wfs_http_connection (void);
#ifdef __cplusplus
}
#endif
#endif /* _GG_WFS_H */
libspatialite-5.1.0/src/headers/spatialite/gg_dxf.h 0000644 0001750 0001750 00000070436 14463127014 017250 0000000 0000000 /*
gg_dxf.h -- Gaia common support for DXF files
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_dxf.h
Geometry handling functions: DXF files
*/
#ifndef _GG_DXF_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_DXF_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constant values for DXF */
/** import distinct layers */
#define GAIA_DXF_IMPORT_BY_LAYER 1
/** import layers mixed altogether by type */
#define GAIA_DXF_IMPORT_MIXED 2
/** auto-selects 2D or 3D */
#define GAIA_DXF_AUTO_2D_3D 3
/** always force 2D */
#define GAIA_DXF_FORCE_2D 4
/** always force 3D */
#define GAIA_DXF_FORCE_3D 5
/** don't apply any special Ring handling */
#define GAIA_DXF_RING_NONE 6
/** apply special "linked rings" handling */
#define GAIA_DXF_RING_LINKED 7
/** apply special "unlinked rings" handling */
#define GAIA_DXF_RING_UNLINKED 8
/** DXF version [Writer] */
#define GAIA_DXF_V12 1000
/* data structs */
/**
wrapper for DXF Extra Attribute object
*/
typedef struct gaia_dxf_extra_attr
{
/** pointer to Extra Attribute Key value */
char *key;
/** pointer to Extra Attribute Value string */
char *value;
/** pointer to next item [linked list] */
struct gaia_dxf_extra_attr *next;
} gaiaDxfExtraAttr;
/**
Typedef for DXF Extra Attribute object
\sa gaiaDxfExtraAttr
*/
typedef gaiaDxfExtraAttr *gaiaDxfExtraAttrPtr;
/**
wrapper for DXF Insert object
*/
typedef struct gaia_dxf_insert
{
/** pointer to Block ID string */
char *block_id;
/** X coordinate */
double x;
/** Y coordinate */
double y;
/** Z coordinate */
double z;
/** X scale factor */
double scale_x;
/** Y scale factor */
double scale_y;
/** Z scale factor */
double scale_z;
/** rotation angle */
double angle;
/** boolean flag: contains Text objects */
int hasText;
/** boolean flag: contains Point objects */
int hasPoint;
/** boolean flag: contains Polyline (Linestring) objects */
int hasLine;
/** boolean flag: contains Polyline (Polygon) objects */
int hasPolyg;
/** boolean flag: contains Hatch objects */
int hasHatch;
/** boolean flag: contains 3d Text objects */
int is3Dtext;
/** boolean flag: contains 3d Point objects */
int is3Dpoint;
/** boolean flag: contains 3d Polyline (Linestring) objects */
int is3Dline;
/** boolean flag: contains 3d Polyline (Polygon) objects */
int is3Dpolyg;
/** pointer to first Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr first;
/** pointer to last Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr last;
/** pointer to next item [linked list] */
struct gaia_dxf_insert *next;
} gaiaDxfInsert;
/**
Typedef for DXF Insert object
\sa gaiaDxfText
*/
typedef gaiaDxfInsert *gaiaDxfInsertPtr;
/**
wrapper for DXF Text object
*/
typedef struct gaia_dxf_text
{
/** pointer to Label string */
char *label;
/** X coordinate */
double x;
/** Y coordinate */
double y;
/** Z coordinate */
double z;
/** label rotation angle */
double angle;
/** pointer to first Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr first;
/** pointer to last Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr last;
/** pointer to next item [linked list] */
struct gaia_dxf_text *next;
} gaiaDxfText;
/**
Typedef for DXF Text object
\sa gaiaDxfText
*/
typedef gaiaDxfText *gaiaDxfTextPtr;
/**
wrapper for DXF Point object
*/
typedef struct gaia_dxf_point
{
/** X coordinate */
double x;
/** Y coordinate */
double y;
/** Z coordinate */
double z;
/** pointer to first Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr first;
/** pointer to last Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr last;
/** pointer to next item [linked list] */
struct gaia_dxf_point *next;
} gaiaDxfPoint;
/**
Typedef for DXF Point object
\sa gaiaDxfPoint
*/
typedef gaiaDxfPoint *gaiaDxfPointPtr;
/**
wrapper for DXF Circle object
*/
typedef struct gaia_dxf_circle
{
/** Center X coordinate */
double cx;
/** Center Y coordinate */
double cy;
/** Center Z coordinate */
double cz;
/** radius */
double radius;
} gaiaDxfCircle;
/**
Typedef for DXF Circle object
\sa gaiaDxfCircle
*/
typedef gaiaDxfCircle *gaiaDxfCirclePtr;
/**
wrapper for DXF Arc object
*/
typedef struct gaia_dxf_arc
{
/** Center X coordinate */
double cx;
/** Center Y coordinate */
double cy;
/** Center Z coordinate */
double cz;
/** radius */
double radius;
/** start angle */
double start;
/** stop angle */
double stop;
} gaiaDxfArc;
/**
Typedef for DXF Arc object
\sa gaiaDxfArc
*/
typedef gaiaDxfArc *gaiaDxfArcPtr;
/**
wrapper for DXF Polygon interior hole object
*/
typedef struct gaia_dxf_hole
{
/** total count of points */
int points;
/** array of X coordinates */
double *x;
/** array of Y coordinates */
double *y;
/** array of Z coordinates */
double *z;
/** pointer to next item [linked list] */
struct gaia_dxf_hole *next;
} gaiaDxfHole;
/**
Typedef for DXF Point object
\sa gaiaDxfHole
*/
typedef gaiaDxfHole *gaiaDxfHolePtr;
/**
wrapper for DXF Polyline object
could be a Linestring or a Polygon depending on the is_closed flag
*/
typedef struct gaia_dxf_polyline
{
/** open (Linestring) or closed (Polygon exterior ring) */
int is_closed;
/** total count of points */
int points;
/** array of X coordinates */
double *x;
/** array of Y coordinates */
double *y;
/** array of Z coordinates */
double *z;
/** pointer to first Polygon hole [linked list] */
gaiaDxfHolePtr first_hole;
/** pointer to last Polygon hole [linked list] */
gaiaDxfHolePtr last_hole;
/** pointer to first Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr first;
/** pointer to last Extra Attribute [linked list] */
gaiaDxfExtraAttrPtr last;
/** pointer to next item [linked list] */
struct gaia_dxf_polyline *next;
} gaiaDxfPolyline;
/**
Typedef for DXF Polyline object
\sa gaiaDxfPolyline
*/
typedef gaiaDxfPolyline *gaiaDxfPolylinePtr;
/**
wrapper for DXF Pattern Segment object
*/
typedef struct gaia_dxf_hatch_segm
{
/** start X */
double x0;
/** start Y */
double y0;
/** end X */
double x1;
/** end Y */
double y1;
/** pointer to next item [linked list] */
struct gaia_dxf_hatch_segm *next;
} gaiaDxfHatchSegm;
/**
Typedef for DXF Hatch Segment object
\sa gaiaDxfHatch
*/
typedef gaiaDxfHatchSegm *gaiaDxfHatchSegmPtr;
/**
wrapper for DXF Boundary Path object
*/
typedef struct gaia_dxf_boundary_path
{
/** pointer to first segment */
gaiaDxfHatchSegmPtr first;
/** pointer to last segment */
gaiaDxfHatchSegmPtr last;
/** pointer to next item [linked list] */
struct gaia_dxf_boundary_path *next;
} gaiaDxfBoundaryPath;
/**
Typedef for DXF Boundary Path object
\sa gaiaDxfBoundaryPath
*/
typedef gaiaDxfBoundaryPath *gaiaDxfBoundaryPathPtr;
/**
wrapper for DXF Pattern Hatch object
*/
typedef struct gaia_dxf_hatch
{
/** hatch pattern spacing */
double spacing;
/** hatch line angle */
double angle;
/** hatch line base X */
double base_x;
/** hatch line base Y */
double base_y;
/** hatch line offset X */
double offset_x;
/** hatch line offset Y */
double offset_y;
/** pointer to first Boundary */
gaiaDxfBoundaryPathPtr first;
/** pointer to last Boundary */
gaiaDxfBoundaryPathPtr last;
/** pointer to Boundary geometry */
gaiaGeomCollPtr boundary;
/** pointer to first Pattern segment */
gaiaDxfHatchSegmPtr first_out;
/** pointer to last Pattern segment */
gaiaDxfHatchSegmPtr last_out;
/** pointer to next item [linked list] */
struct gaia_dxf_hatch *next;
} gaiaDxfHatch;
/**
Typedef for DXF Hatch object
\sa gaiaDxfHatch
*/
typedef gaiaDxfHatch *gaiaDxfHatchPtr;
/**
wrapper for DXF Block object
*/
typedef struct gaia_dxf_block
{
/** Boolean flag: this block is referenced by some Insert */
int hasInsert;
/** pointer to Layer Name string */
char *layer_name;
/** pointer to Block ID string */
char *block_id;
/** pointer to first DXF Text object [linked list] */
gaiaDxfTextPtr first_text;
/** pointer to last DXF Text object [linked list] */
gaiaDxfTextPtr last_text;
/** pointer to first DXF Point object [linked list] */
gaiaDxfPointPtr first_point;
/** pointer to last DXF Point object [linked list] */
gaiaDxfPointPtr last_point;
/** pointer to first DXF Polyline (Linestring) object [linked list] */
gaiaDxfPolylinePtr first_line;
/** pointer to last DXF Polyline (Linestring) object [linked list] */
gaiaDxfPolylinePtr last_line;
/** pointer to first DXF Polyline (Polygon) object [linked list] */
gaiaDxfPolylinePtr first_polyg;
/** pointer to last DXF Polyline (Polygon) object [linked list] */
gaiaDxfPolylinePtr last_polyg;
/** pointer to first DXF Hatch object [linked list] */
gaiaDxfHatchPtr first_hatch;
/** pointer to last DXF Hatch object [linked list] */
gaiaDxfHatchPtr last_hatch;
/** boolean flag: contains 3d Text objects */
int is3Dtext;
/** boolean flag: contains 3d Point objects */
int is3Dpoint;
/** boolean flag: contains 3d Polyline (Linestring) objects */
int is3Dline;
/** boolean flag: contains 3d Polyline (Polygon) objects */
int is3Dpolyg;
/** pointer to next item [linked list] */
struct gaia_dxf_block *next;
} gaiaDxfBlock;
/**
Typedef for DXF Block object
\sa gaiaDxfBlock
*/
typedef gaiaDxfBlock *gaiaDxfBlockPtr;
/**
wrapper for DXF Layer object
*/
typedef struct gaia_dxf_layer
{
/** pointer to Layer Name string */
char *layer_name;
/** pointer to first DXF Text object [linked list] */
gaiaDxfTextPtr first_text;
/** pointer to last DXF Text object [linked list] */
gaiaDxfTextPtr last_text;
/** pointer to first DXF Point object [linked list] */
gaiaDxfPointPtr first_point;
/** pointer to lasst DXF Point object [linked list] */
gaiaDxfPointPtr last_point;
/** pointer to first DXF Polyline (Linestring) object [linked list] */
gaiaDxfPolylinePtr first_line;
/** pointer to last DXF Polyline (Linestring) object [linked list] */
gaiaDxfPolylinePtr last_line;
/** pointer to first DXF Polyline (Polygon) object [linked list] */
gaiaDxfPolylinePtr first_polyg;
/** pointer to last DXF Polyline (Polygon) object [linked list] */
gaiaDxfPolylinePtr last_polyg;
/** pointer to first DXF Hatch object [linked list] */
gaiaDxfHatchPtr first_hatch;
/** pointer to last DXF Hatch object [linked list] */
gaiaDxfHatchPtr last_hatch;
/** pointer to first DXF Insert Text object [linked list] */
gaiaDxfInsertPtr first_ins_text;
/** pointer to last DXF Insert Text object [linked list] */
gaiaDxfInsertPtr last_ins_text;
/** pointer to first DXF Insert Point object [linked list] */
gaiaDxfInsertPtr first_ins_point;
/** pointer to last DXF Insert Point object [linked list] */
gaiaDxfInsertPtr last_ins_point;
/** pointer to first DXF Insert Polyline (Linestring) object [linked list] */
gaiaDxfInsertPtr first_ins_line;
/** pointer to last DXF Insert Polyline (Linestring) object [linked list] */
gaiaDxfInsertPtr last_ins_line;
/** pointer to first DXF Insert Polyline (Polygon) object [linked list] */
gaiaDxfInsertPtr first_ins_polyg;
/** pointer to last DXF Insert Polyline (Polygon) object [linked list] */
gaiaDxfInsertPtr last_ins_polyg;
/** pointer to first DXF Insert Hatch object [linked list] */
gaiaDxfInsertPtr first_ins_hatch;
/** pointer to last DXF Insert Hatch object [linked list] */
gaiaDxfInsertPtr last_ins_hatch;
/** boolean flag: contains 3d Text objects */
int is3Dtext;
/** boolean flag: contains 3d Point objects */
int is3Dpoint;
/** boolean flag: contains 3d Polyline (Linestring) objects */
int is3Dline;
/** boolean flag: contains 3d Polyline (Polygon) objects */
int is3Dpolyg;
/** boolean flag: contains 3d Insert Text objects */
int is3DinsText;
/** boolean flag: contains 3d Insert Point objects */
int is3DinsPoint;
/** boolean flag: contains 3d Insert Polyline (Linestring) objects */
int is3DinsLine;
/** boolean flag: contains 3d Insert Polyline (Polygon) objects */
int is3DinsPolyg;
/** boolean flag: contains Text Extra Attributes */
int hasExtraText;
/** boolean flag: contains Point Extra Attributes */
int hasExtraPoint;
/** boolean flag: contains Polyline (Linestring) Extra Attributes */
int hasExtraLine;
/** boolean flag: contains Polyline (Polygon) Extra Attributes */
int hasExtraPolyg;
/** boolean flag: contains Insert Text Extra Attributes */
int hasExtraInsText;
/** boolean flag: contains Insert Text Extra Attributes */
int hasExtraInsPoint;
/** boolean flag: contains Insert Polyline (Linestring) Extra Attributes */
int hasExtraInsLine;
/** boolean flag: contains Insert Polyline (Polygon) Extra Attributes */
int hasExtraInsPolyg;
/** pointer to next item [linked list] */
struct gaia_dxf_layer *next;
} gaiaDxfLayer;
/**
Typedef for DXF Layer object
\sa gaiaDxfLayer
*/
typedef gaiaDxfLayer *gaiaDxfLayerPtr;
/**
wrapper for DXF Parser object
*/
typedef struct gaia_dxf_parser
{
/** OUT: origin/input filename */
char *filename;
/** OUT: pointer to first DXF Layer object [linked list] */
gaiaDxfLayerPtr first_layer;
/** OUT: pointer to last DXF Layer object [linked list] */
gaiaDxfLayerPtr last_layer;
/** OUT: pointer to first DXF Block object [linked list] */
gaiaDxfBlockPtr first_block;
/** OUT: pointer to last DXF Block object [linked list] */
gaiaDxfBlockPtr last_block;
/** IN: parser option - dimension handlig */
int force_dims;
/** IN: parser option - the SRID */
int srid;
/** IN: parser option - pointer the single Layer Name string */
const char *selected_layer;
/** IN: parser option - pointer to prefix string for DB tables */
const char *prefix;
/** IN: parser option - linked rings special handling */
int linked_rings;
/** IN: parser option - unlinked rings special handling */
int unlinked_rings;
/** internal parser variable */
int line_no;
/** internal parser variable */
int op_code_line;
/** internal parser variable */
int op_code;
/** internal parser variable */
int section;
/** internal parser variable */
int tables;
/** internal parser variable */
int blocks;
/** internal parser variable */
int entities;
/** internal parser variable */
int is_layer;
/** internal parser variable */
int is_block;
/** internal parser variable */
int is_text;
/** internal parser variable */
int is_point;
/** internal parser variable */
int is_polyline;
/** internal parser variable */
int is_lwpolyline;
/** internal parser variable */
int is_line;
/** internal parser variable */
int is_circle;
/** internal parser variable */
int is_arc;
/** internal parser variable */
int is_vertex;
/** internal parser variable */
int is_hatch;
/** internal parser variable */
int is_hatch_boundary;
/** internal parser variable */
int is_insert;
/** internal parser variable */
int eof;
/** internal parser variable */
int error;
/** internal parser variable */
char *curr_layer_name;
/** internal parser variable */
gaiaDxfText curr_text;
/** internal parser variable */
gaiaDxfInsert curr_insert;
/** internal parser variable */
gaiaDxfBlock curr_block;
/** internal parser variable */
gaiaDxfPoint curr_point;
/** internal parser variable */
gaiaDxfPoint curr_end_point;
/** internal parser variable */
gaiaDxfCircle curr_circle;
/** internal parser variable */
gaiaDxfArc curr_arc;
/** internal parser variable */
int is_closed_polyline;
/** internal parser variable */
gaiaDxfPointPtr first_pt;
/** internal parser variable */
gaiaDxfPointPtr last_pt;
/** internal parser variable */
char *extra_key;
/** internal parser variable */
char *extra_value;
/** internal parser variable */
gaiaDxfExtraAttrPtr first_ext;
/** internal parser variable */
gaiaDxfExtraAttrPtr last_ext;
/** internal parser variable */
gaiaDxfHatchPtr curr_hatch;
/** internal parser variable */
int undeclared_layers;
} gaiaDxfParser;
/**
Typedef for DXF Layer object
\sa gaiaDxfParser
*/
typedef gaiaDxfParser *gaiaDxfParserPtr;
/**
wrapper for DXF Write object
*/
typedef struct gaia_dxf_write
{
/** IN: output DXF file handle */
FILE *out;
/** IN: coord's precision (number of decimal digits) */
int precision;
/** IN: DXF version number */
int version;
/** OUT: count of exported geometries */
int count;
/** OUT: error flag */
int error;
} gaiaDxfWriter;
/**
Typedef for DXF Writer object
*/
typedef gaiaDxfWriter *gaiaDxfWriterPtr;
/* function prototypes */
/**
Creates a DXF Parser object
\param srid the SRID value to be used for all Geometries
\param force_dims should be one of GAIA_DXF_AUTO_2D_3D, GAIA_DXF_FORCE_2D
or GAIA_DXF_FORCE_3D
\param prefix an optional prefix to be used for DB target tables
(could be NULL)
\param selected_layers if set, only the DXF Layer of corresponding name will
be imported (could be NULL)
\param special_rings rings handling: should be one of GAIA_DXF_RING_NONE,
GAIA_DXF_RING_LINKED of GAIA_DXF_RING_UNLINKED
\return the pointer to a DXF Parser object
\sa gaiaDestroyDxfParser, gaiaParseDxfFile, gaiaLoadFromDxfParser
\note the DXF Parser object corresponds to dynamically allocated memory:
so you are responsible to destroy this object before or later by invoking
gaiaDestroyDxfParser().
*/
GAIAGEO_DECLARE gaiaDxfParserPtr gaiaCreateDxfParser (int srid,
int force_dims,
const char *prefix,
const char
*selected_layer,
int special_rings);
/**
Destroying a DXF Parser object
\param parser pointer to DXF Parser object
\sa gaiaCreateDxfParser
\note the pointer to the DXF Parser object to be finalized is expected
to be the one returned by a previous call to gaiaCreateDxfParser.
*/
GAIAGEO_DECLARE void gaiaDestroyDxfParser (gaiaDxfParserPtr parser);
/**
Parsing a DXF file
\param parser pointer to DXF Parser object
\param dxf_path pathname of the DXF external file to be parsed
\return 0 on failure, any other value on success
\sa gaiaParseDxfFile_r,
gaiaCreateDxfParser, gaiaDestroyDxfParser, gaiaLoadFromDxfParser
\note the pointer to the DXF Parser object is expected to be the one
returned by a previous call to gaiaCreateDxfParser.
A DXF Parser object can be used only a single time to parse a DXF file.\n
not reentrant and thread unsafe.
*/
GAIAGEO_DECLARE int gaiaParseDxfFile (gaiaDxfParserPtr parser,
const char *dxf_path);
/**
Parsing a DXF file
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param parser pointer to DXF Parser object
\param dxf_path pathname of the DXF external file to be parsed
\return 0 on failure, any other value on success
\sa gaiaParseDxfFile,
gaiaCreateDxfParser, gaiaDestroyDxfParser, gaiaLoadFromDxfParser
\note the pointer to the DXF Parser object is expected to be the one
returned by a previous call to gaiaCreateDxfParser.
A DXF Parser object can be used only a single time to parse a DXF file.\n
reentrant and thread-safe.
*/
GAIAGEO_DECLARE int gaiaParseDxfFile_r (const void *p_cache,
gaiaDxfParserPtr parser,
const char *dxf_path);
/**
Populating a DB so to permanently store all Geometries from a DXF Parser
\param db_handle handle to a valid DB connection
\param parser pointer to DXF Parser object
\param mode should be one of GAIA_DXF_IMPORT_BY_LAYER or GAIA_DXF_IMPORT_MIXED
\param append boolean flag: if set and some required DB table already exists
will attempt to append further rows into the existing table.
otherwise an error will be returned.
\return 0 on failure, any other value on success
\sa gaiaCreateDxfParser, gaiaDestroyDxfParser, gaiaParseDxfFile
\note the pointer to the DXF Parser object is expected to be the one
returned by a previous call to gaiaCreateDxfParser and previously used
for a succesfull call to gaiaParseDxfFile
*/
GAIAGEO_DECLARE int gaiaLoadFromDxfParser (sqlite3 * db_handle,
gaiaDxfParserPtr parser,
int mode, int append);
/**
Initializing a DXF Writer Object
\param writer pointer to the gaiaDxfWriter object to be initialized
\param out file handle to DXF output file
\param precision number of decimal digits for any coordinate
\param version currently always expected to be GAIA_DXF_V12
\return 0 on failure, any other value on success
\sa gaiaDxfWriteHeader, gaiaExportDxf
*/
GAIAGEO_DECLARE int gaiaDxfWriterInit (gaiaDxfWriterPtr dxf,
FILE * out, int precision,
int version);
/**
Writing the DXF Header
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param minx the minimum X coordinate contained within the DXF
\param minx the minimum Y coordinate contained within the DXF
\param minx the minimum Z coordinate contained within the DXF
\param minx the maximum X coordinate contained within the DXF
\param minx the maximum Y coordinate contained within the DXF
\param minx the maximum Z coordinate contained within the DXF
\return 0 on failure, any other value on success
\sa gaiaDxfWriterInit, gaiaDxfWriteFooter, gaiaDxfWriteTables, gaiaDxfWriteEntities
*/
GAIAGEO_DECLARE int
gaiaDxfWriteHeader (gaiaDxfWriterPtr dxf, double minx, double miny,
double minz, double maxx, double maxy, double maxz);
/**
Writing a DXF Entities Section Header
\param dxf pointer to a properly initialized gaiaDxfWriter object
\return 0 on failure, any other value on success
\sa gaiaDxfWriteHeader
*/
GAIAGEO_DECLARE int gaiaDxfWriteFooter (gaiaDxfWriterPtr dxf);
/**
Writing the DXF Tables Section Header
\param dxf pointer to a properly initialized gaiaDxfWriter object
\return 0 on failure, any other value on success
\sa gaiaDxfWriteHeader, gaiaDxfWriteEndSection
*/
GAIAGEO_DECLARE int gaiaDxfWriteTables (gaiaDxfWriterPtr dxf);
/**
Writing a DXF Table/Layer definition
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the layer
\return 0 on failure, any other value on success
\sa gaiaDxfWriteTables, gaiaDxfWriteEndSection
*/
GAIAGEO_DECLARE int gaiaDxfWriteLayer (gaiaDxfWriterPtr dxf,
const char *layer_name);
/**
Writing a DXF Entities Section Header
\param dxf pointer to a properly initialized gaiaDxfWriter object
\return 0 on failure, any other value on success
\sa gaiaDxfWriteHeader, gaiaDxfWriteEndSection, gaiaDxfWritePoint,
gaiaDxfWriteText, gaiaDxfWriteLine, gaiaDxfWriteRing, gaiaDxfWriteGeometry
*/
GAIAGEO_DECLARE int gaiaDxfWriteEntities (gaiaDxfWriterPtr dxf);
/**
Writing a DXF Entities Section Header
\param dxf pointer to a properly initialized gaiaDxfWriter object
\return 0 on failure, any other value on success
\sa gaiaDxfWriteTables, gaiaDxfWriteEntities
*/
GAIAGEO_DECLARE int gaiaDxfWriteEndSection (gaiaDxfWriterPtr dxf);
/**
Writing a DXF Point Entity
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the corresponding layer
\param x X coordinate value
\param y Y coordinate value
\param z Z coordinate value
\return 0 on failure, any other value on success
\sa gaiaDxfWriteEntities, gaiaDxfWriteEndSection, gaiaDxfWriteText,
gaiaDxfWriteLine, gaiaDxfWriteRing, gaiaDxfWriteGeometry
*/
GAIAGEO_DECLARE int gaiaDxfWritePoint (gaiaDxfWriterPtr dxf,
const char *layer_name, double x,
double y, double z);
/**
Writing a DXF Text Entity
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the corresponding layer
\param x X coordinate value
\param y Y coordinate value
\param z Z coordinate value
\param label text string containing the label value
\param text_height height of the text in map units
\param angle text rotation angle
\return 0 on failure, any other value on success
\sa gaiaDxfWriteEntities, gaiaDxfWriteEndSection, gaiaDxfWritePoint,
gaiaDxfWriteLine, gaiaDxfWriteRing, gaiaDxfWriteGeometry
*/
GAIAGEO_DECLARE int gaiaDxfWriteText (gaiaDxfWriterPtr dxf,
const char *layer_name, double x,
double y, double z,
const char *label,
double text_height, double angle);
/**
Writing a DXF Polyline (opened) Entity
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the corresponding layer
\param line pointer to the internal Linestring to be exported into the DXF
\return 0 on failure, any other value on success
\sa gaiaDxfWriteEntities, gaiaDxfWriteEndSection, gaiaDxfWritePoint,
gaiaDxfWriteText, gaiaDxfWriteRing, gaiaDxfWriteGeometry
*/
GAIAGEO_DECLARE int
gaiaDxfWriteLine (gaiaDxfWriterPtr dxf, const char *layer_name,
gaiaLinestringPtr line);
/**
Writing a DXF Polyline (closed) Entity
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the corresponding layer
\param line pointer to the internal Ring to be exported into the DXF
\return 0 on failure, any other value on success
\sa gaiaDxfWriteEntities, gaiaDxfWriteEndSection, gaiaDxfWritePoint,
gaiaDxfWriteText, gaiaDxfWriteLine, gaiaDxfWriteGeometry
*/
GAIAGEO_DECLARE int
gaiaDxfWriteRing (gaiaDxfWriterPtr dxf, const char *layer_name,
gaiaRingPtr ring);
/**
Writing a DXF generic Entity
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param layer_name name of the corresponding layer
\param line pointer to the internal Ring to be exported into the DXF
\param label text string containing the label value (could be NULL)
\param text_height only for Text Labels: ingnored in any other case.
\param text_rotation only for Text Labels: ingnored in any other case.
\return 0 on failure, any other value on success
\sa gaiaDxfWriteEntities, gaiaDxfWriteEndSection, gaiaDxfWritePoint,
gaiaDxfWriteText, gaiaDxfWriteLine, gaiaDxfWriteRing
*/
GAIAGEO_DECLARE int
gaiaDxfWriteGeometry (gaiaDxfWriterPtr dxf, const char *layer_name,
const char *label, double text_height,
double text_rotation, gaiaGeomCollPtr geometry);
/**
Exporting a complex DXF file
\param dxf pointer to a properly initialized gaiaDxfWriter object
\param db_hanlde handle to the current DB connection
\param sql a text string defining the SQL query to be used for
extracting all geometries/entities to be exported into the output DXF
\param layer_col_name name of the SQL resultset column containing the Layer name
\param geom_col_name name of the SQL resultset column containing Geometries
\param label_col_name name of the SQL resultset column containing Label values
(could be NULL)
\param text_height_col_name name of the SQL resultset column containing Text Height values
(could be NULL)
\param text_rotation_col_name name of the SQL resultset column containing Text Rotation values
(could be NULL)
\param geom_filter an optional arbitrary Geometry to be used as a Spatial Filter
(could be NULL)
\return 0 on failure; the total count of exported entities on success
\sa gaiaDxfWriterInit
*/
GAIAGEO_DECLARE int
gaiaExportDxf (gaiaDxfWriterPtr dxf, sqlite3 * db_handle,
const char *sql, const char *layer_col_name,
const char *geom_col_name, const char *label_col_name,
const char *text_height_col_name,
const char *text_rotation_col_name,
gaiaGeomCollPtr geom_filter);
#ifdef __cplusplus
}
#endif
#endif /* _GG_DXF_H */
libspatialite-5.1.0/src/headers/spatialite/spatialite_ext.h 0000644 0001750 0001750 00000005465 14463127014 021031 0000000 0000000 /*
spatialite_ext.h -- Gaia support for SQLite extensions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
SPATIALITE_PRIVATE int virtualshape_extension_init (void *db);
SPATIALITE_PRIVATE int virtualdbf_extension_init (void *db);
SPATIALITE_PRIVATE int virtualtext_extension_init (void *db);
SPATIALITE_PRIVATE int virtualXL_extension_init (void *db);
SPATIALITE_PRIVATE int virtualnetwork_extension_init (void *db);
SPATIALITE_PRIVATE int virtualrouting_extension_init (void *db);
SPATIALITE_PRIVATE int virtualfdo_extension_init (void *db);
SPATIALITE_PRIVATE int virtualbbox_extension_init (void *db,
const void *p_cache);
SPATIALITE_PRIVATE int mbrcache_extension_init (void *db);
SPATIALITE_PRIVATE int virtual_spatialindex_extension_init (void *db);
SPATIALITE_PRIVATE int virtual_elementary_extension_init (void *db);
SPATIALITE_PRIVATE int virtual_knn_extension_init (void *db);
SPATIALITE_PRIVATE int virtual_knn2_extension_init (void *db);
SPATIALITE_PRIVATE int virtual_xpath_extension_init (void *db,
const void *p_cache);
SPATIALITE_PRIVATE int virtualgpkg_extension_init (void *db);
SPATIALITE_PRIVATE int virtualgeojson_extension_init (void *db);
libspatialite-5.1.0/src/headers/spatialite/sqlite.h 0000644 0001750 0001750 00000004670 14463127014 017310 0000000 0000000 /*
sqlite.h -- supporting SQLite headers in a flexible way
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2013-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Pepijn Van Eeckhoudt
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#ifndef _SPATIALITE_SQLITE_H
#define _SPATIALITE_SQLITE_H
#ifdef LOADABLE_EXTENSION /* loadable-extension only */
#ifdef SPL_AMALGAMATION /* spatialite-amalgamation */
#include
#else
#include
#endif
/* We can't use SQLITE_EXTENSION_INIT1 as this is an intializer in recent version of sqlite */
extern const sqlite3_api_routines *sqlite3_api;
#else /* ordinary lib */
#ifdef SPL_AMALGAMATION /* spatialite-amalgamation */
#include
#else
#include
#endif
#endif
#ifndef SQLITE_DETERMINISTIC
/* probably SQLite < 3.8.3 - attempting to fix */
#define SQLITE_DETERMINISTIC SQLITE_UTF8
#endif
#endif
libspatialite-5.1.0/src/headers/spatialite/debug.h 0000644 0001750 0001750 00000005054 14463127014 017072 0000000 0000000 /*
debug.h -- abstract defs for standard output functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2012-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Pepijn Van Eeckhoudt
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#ifndef SPATIALITE_DEBUG_H
#define SPATIALITE_DEBUG_H
#ifdef __ANDROID__ /* Android specific */
#include
#ifdef DEBUG
#define spatialite_d(...)
#else
#define spatialite_d(...) __android_log_print(ANDROID_LOG_DEBUG, "Spatialite", __VA_ARGS__)
#endif
#define spatialite_i(...) __android_log_print(ANDROID_LOG_INFO, "Spatialite", __VA_ARGS__)
#define spatialite_e(...) __android_log_print(ANDROID_LOG_ERROR, "Spatialite", __VA_ARGS__)
#else /* any other standard platform (Win, Linux, Mac) */
#include
#ifdef DEBUG
#define spatialite_d(...)
#else
#define spatialite_d(...) fprintf(stdout, __VA_ARGS__)
#endif
#define spatialite_i(...) fprintf(stdout, __VA_ARGS__)
#define spatialite_e(...) fprintf(stderr, __VA_ARGS__)
#endif /* platform specific */
#endif
libspatialite-5.1.0/src/headers/spatialite/geopackage.h 0000644 0001750 0001750 00000015307 14463127014 020074 0000000 0000000 /*
GeoPackage extensions for SpatiaLite / SQLite
version 5.1.0, 2023 August 4
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is GeoPackage Extensions
The Initial Developer of the Original Code is Brad Hards (bradh@frogmouth.net)
Portions created by the Initial Developer are Copyright (C) 2012-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Sandro Furieri (a.furieri@lqt.it)
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file geopackage.h
GeoPackage: supporting functions and constants
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef _WIN32
#ifdef DLL_EXPORT
#define GEOPACKAGE_DECLARE __declspec(dllexport)
#define GEOPACKAGE_PRIVATE
#else
#define GEOPACKAGE_DECLARE extern
#define GEOPACKAGE_PRIVATE
#endif
#else
#define GEOPACKAGE_DECLARE __attribute__ ((visibility("default")))
#define GEOPACKAGE_PRIVATE __attribute__ ((visibility("hidden")))
#endif
#endif
#ifndef _GEOPACKAGE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GEOPACKAGE_H
#endif
#include "sqlite.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include
/* Internal geopackage SQL function implementation */
GEOPACKAGE_PRIVATE void fnct_gpkgCreateBaseTables (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgCreateTilesTable (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgCreateTilesZoomLevel (sqlite3_context *
context, int argc,
sqlite3_value **
argv);
GEOPACKAGE_PRIVATE void fnct_gpkgInsertEpsgSRID (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgAddTileTriggers (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgGetNormalRow (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgGetNormalZoom (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgGetImageType (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgAddGeometryColumn (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePoint (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointWithSRID (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointZ (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointZWithSRID (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointM (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointMWithSRID (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointZM (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgMakePointZMWithSRID (sqlite3_context *
context, int argc,
sqlite3_value **
argv);
GEOPACKAGE_PRIVATE void fnct_ToGPB (sqlite3_context * context, int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_GeomFromGPB (sqlite3_context * context,
int argc, sqlite3_value ** argv);
GEOPACKAGE_DECLARE gaiaGeomCollPtr gaiaFromGeoPackageGeometryBlob (const
unsigned
char
*gpb,
unsigned
int
gpb_len);
/* Sandro Furieri - 2014-05-19 */
GEOPACKAGE_DECLARE int gaiaIsValidGPB (const unsigned char *gpb,
int gpb_len);
GEOPACKAGE_DECLARE int gaiaGetSridFromGPB (const unsigned char *gpb,
int gpb_len);
GEOPACKAGE_DECLARE int gaiaIsEmptyGPB (const unsigned char *gpb,
int gpb_len);
GEOPACKAGE_DECLARE int gaiaGetEnvelopeFromGPB (const unsigned char *gpb,
int gpb_len, double *min_x,
double *max_x,
double *min_y,
double *max_y, int *has_z,
double *min_z,
double *max_z, int *has_m,
double *min_m,
double *max_m);
GEOPACKAGE_DECLARE char *gaiaGetGeometryTypeFromGPB (const unsigned char
*gpb, int gpb_len);
GEOPACKAGE_PRIVATE void fnct_IsValidGPB (sqlite3_context * context,
int argc, sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_GPKG_IsAssignable (sqlite3_context * context,
int argc,
sqlite3_value ** argv);
GEOPACKAGE_PRIVATE void fnct_gpkgAddGeometryTriggers (sqlite3_context *
context, int argc,
sqlite3_value **
argv);
GEOPACKAGE_PRIVATE void fnct_gpkgAddGeometryTriggers (sqlite3_context *
context, int argc,
sqlite3_value **
argv);
GEOPACKAGE_PRIVATE void fnct_gpkgAddSpatialIndex (sqlite3_context *
context, int argc,
sqlite3_value ** argv);
/* end Sandro Furieri - 2014-05-19 */
/* Sandro Furieri - 2015-06-14 */
GEOPACKAGE_DECLARE void
gaiaToGPB (gaiaGeomCollPtr geom, unsigned char **result, int *size);
/* end Sandro Furieri - 2015-06-14 */
/* Markers for unused arguments / variable */
#if __GNUC__
#define UNUSED __attribute__ ((__unused__))
#else
#define UNUSED
#endif
#ifdef __cplusplus
}
#endif
#endif
libspatialite-5.1.0/src/headers/spatialite/control_points.h 0000644 0001750 0001750 00000020041 14463127014 021051 0000000 0000000 /*
control_points.h -- Gaia implementation of RMSE and TPS Control Points
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file control_points.h
Auxiliary/helper functions
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef DLL_EXPORT
#define GAIACP_DECLARE __declspec(dllexport)
#else
#define GAIACP_DECLARE extern
#endif
#endif
#ifndef _GAIACP_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIACP_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
Typedef for GaiaControPoints object (opaque, hidden)
\sa GaiaControlPointsPtr
*/
typedef struct opaque_control_points GaiaControlPoints;
/**
Typedef for GaiaControPointsPtr object pointer (opaque, hidden)
\sa GaiaControlPoints
*/
typedef GaiaControlPoints *GaiaControlPointsPtr;
/**
Typedef for GaiaPolynomialCoeffs object (opaque, hidden)
\sa GaiaPolynomialCoeffsPtr
*/
typedef struct priv_polynomial_coeffs GaiaPolynomialCoeffs;
/**
Typedef for GaiaPolynomialCoeffsPtr object pointer (opaque, hidden)
\sa GaiaPolynomialCoeffs
*/
typedef GaiaPolynomialCoeffs *GaiaPolynomialCoeffsPtr;
/* function prototypes */
/**
Creates a Control Points container (opaque object)
\param allocation_incr how many Control Points should be allocated
every time that necessity arises to increment the internal storage
\param has3d true if the Control Points are all expected to be 3D
\param order polynomial order: 1 or 2 or 3
\param tps true if the solution method must be Thin Plate Spline
\return the handle of the container object, or NULL on failure
\sa gaiaFreeControlPoints, gaiaAddControlPoint3D, gaiaAddControlPoint2D,
gaiaAffineFromControlPoints
\note you must properly destroy the container object when it
isn't any longer used.
*/
GAIACP_DECLARE GaiaControlPointsPtr gaiaCreateControlPoints (int
allocation_incr,
int has3d,
int order,
int tps);
/**
Destroys a Control Points container (opaque object)
\param cp_handle the handle identifying the container object
(returned by a previous call to gaiaCreateControlPoints).
\sa gaiaCreateControlPoints
*/
GAIACP_DECLARE void gaiaFreeControlPoints (GaiaControlPointsPtr cp_handle);
/**
Add a further Control Point 3D to the container (opaque object)
\param cp_handle the handle identifying the container object
(returned by a previous call to gaiaCreateControlPoints).
\param x0 X coordinate of the first Point.
\param y0 Y coordinate of the first Point.
\param z0 Z coordinate of the first Point.
\param x1 X coordinate of the second Point.
\param y1 Y coordinate of the second Point.
\param z1 Z coordinate of the second Point.
\return 0 on failure: any other different value on success.
\sa gaiaCreateControlPoints, gaiaAddControlPoint2D
*/
GAIACP_DECLARE int gaiaAddControlPoint3D (GaiaControlPointsPtr cp_handle,
double x0, double y0, double z0,
double x1, double y1, double z1);
/**
Add a further Control Point 2D to the container (opaque object)
\param cp_handle the handle identifying the container object
(returned by a previous call to gaiaCreateControlPoints).
\param x0 X coordinate of the first Point.
\param y0 Y coordinate of the first Point.
\param x1 X coordinate of the second Point.
\param y1 Y coordinate of the second Point.
\return 0 on failure: any other different value on success.
\sa gaiaCreateControlPoints, gaiaAddControlPoint3D
*/
GAIACP_DECLARE int gaiaAddControlPoint2D (GaiaControlPointsPtr cp_handle,
double x0, double y0, double x1,
double y1);
/**
Resolves a Control Point set by computing an Affine Transform Matrix
\param cp_handle the handle identifying the container object
(returned by a previous call to gaiaCreateControlPoints).
\param blob on completion this variable will contain a BLOB-encoded
Polynomial coeffs object
\param blob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
\sa gaiaCreateControlPoints, gaiaPolynomialIsValid, gaiaPolynomialAsText,
gaiaPolynomialTransformGeometry
*/
GAIACP_DECLARE int gaiaCreatePolynomialCoeffs (GaiaControlPointsPtr
cp_handle,
unsigned char **blob,
int *blob_sz);
/**
Testing a BLOB-Polynomial for validity
\param blob pointer to a BLOB-encoded Polynomial coeffs object
\param blob_sz BLOB's size (in bytes)
\return TRUE if the BLOB really is of the BLOB-Polynomial type; FALSE if not.
\sa gaiaCreatePolynomialCoeffs, gaiaPolynomialAsText
*/
GAIACP_DECLARE int gaiaPolynomialIsValid (const unsigned char *blob,
int blob_sz);
/**
Printing a textual represention from a BLOB-Matrix
\param blob pointer to a BLOB-encoded Polynomial coeffs object
\param blob_sz BLOB's size (in bytes)
\return a text string; NULL on failure.
\sa gaiaCreateControlPoints, gaiaPolynomialIsValid,
gaiaPolynomialTransformGeometry
\note you are responsible to destroy (before or after) any text
string returned by this function by calling sqlite3_free().
*/
GAIACP_DECLARE char *gaiaPolynomialAsText (const unsigned char *blob,
int blob_sz);
/**
Transforming a Geometry accordingly to an Affine Transform Matrix
\param geom the input Geometry
\param blob pointer to a BLOB-encoded Polynomial coeffs object
\param blob_sz BLOB's size (in bytes)
\return 0 pointer to the transformed Geometry or NULL on failure.
\sa gaiaCreateControlPoints, gaiaPolynomialIsValid,
gaiaPolynomialAsText
\note you are responsible to destroy (before or after) any Geometry
returned by this function.
*/
GAIACP_DECLARE gaiaGeomCollPtr
gaiaPolynomialTransformGeometry (gaiaGeomCollPtr geom,
const unsigned char *blob,
int blob_sz);
/**
Converts a Polynomial coeffs object into an Affine Transsform Matrix
\param iblob pointer to a BLOB-encoded Polynomial coeffs object
\param iblob_sz BLOB's size (in bytes)
\param oblob on completion this variable will contain a BLOB-encoded
Affine Transform Matrix object
\param oblob_sz on completion this variable will contain the BLOB's size
(in bytes)
\return 0 on failure: any other different value on success.
\sa gaiaCreateControlPoints, gaiaPolynomialIsValid, gaiaPolynomialAsText,
gaiaPolynomialTransformGeometry, gaiaPolynomialToMatrix
*/
GAIACP_DECLARE int gaiaPolynomialToMatrix (const unsigned char *iblob,
int iblob_sz,
unsigned char **oblob,
int *oblob_sz);
#ifdef __cplusplus
}
#endif
#endif /* _GAIACP_H */
libspatialite-5.1.0/src/headers/spatialite/gaia_topology.h 0000644 0001750 0001750 00000120130 14463127014 020632 0000000 0000000 /*
gaia_topology.h -- Gaia common support for Topology
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2015-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaia_topology.h
Topology handling functions and constants
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* stdio.h included for FILE objects. */
#include
#ifdef DLL_EXPORT
#define GAIATOPO_DECLARE __declspec(dllexport)
#else
#define GAIATOPO_DECLARE extern
#endif
#endif
#ifndef _GAIATOPO_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIATOPO_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
Typedef for Topology Accessor Object (opaque, hidden)
\sa GaiaTopologyAccessorPtr
*/
typedef struct gaia_topology_accessor GaiaTopologyAccessor;
/**
Typedef for Topology Accessor Object pointer (opaque, hidden)
\sa GaiaTopologyAccessor
*/
typedef struct gaia_topology_accessor *GaiaTopologyAccessorPtr;
/**
returns the last Topology exception (if any)
\param topo_name unique name identifying the Topology.
\return pointer to the last Topology error message: may be NULL if
no Topology error is currently pending.
*/
GAIATOPO_DECLARE const char *gaiaTopologyGetLastException (const char
*topo_name);
/**
creates a new Topology and all related DB objects
\param handle pointer to the current DB connection.
\param topo_name unique name identifying the Topology.
\param srid a spatial reference identifier.
\param tolerance a tolerance factor measuren in the same units defined
by the associated SRID.
\param has_z boolean: if TRUE this Topology supports 3D (XYZ).
\return 0 on failure: any other value on success.
\sa gaiaTopologyDrop
*/
GAIATOPO_DECLARE int gaiaTopologyCreate (sqlite3 * handle,
const char *topo_name, int srid,
double tolerance, int has_z);
/**
completely drops an already existing Topology and removes all related DB objects
\param handle pointer to the current DB connection.
\param topo_name unique name identifying the Topology.
\return 0 on failure: any other value on success.
\sa gaiaTopologyCreate
*/
GAIATOPO_DECLARE int gaiaTopologyDrop (sqlite3 * handle,
const char *topo_name);
/**
creates an opaque Topology Accessor object starting from its DB configuration
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param topo_name unique name identifying the Topology.
\return the pointer to newly created Topology Accessor Object: NULL on failure.
\sa gaiaTopologyCreate, gaiaTopologyDestroy, gaiaTopologyFromCache,
gaiaGetTopology
\note you are responsible to destroy (before or after) any allocated
Topology Accessor Object. The Topology Accessor once created will be
preserved within the internal connection cache for future references.
*/
GAIATOPO_DECLARE GaiaTopologyAccessorPtr gaiaTopologyFromDBMS (sqlite3 *
handle,
const void
*cache,
const char
*topo_name);
/**
retrieves a Topology configuration from DB
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param topo_name unique name identifying the Topology.
\param topology_name on completion will point to the real Topology name.
\param srid on completion will contain the Topology SRID.
\param tolerance on completion will contain the tolerance argument.
\param has_z on completion will report if the Topology is of the 3D type.
\return 1 on success: NULL on failure.
\sa gaiaTopologyCreate, gaiaTopologyDestroy, gaiaTopologyFromCache,
gaiaGetTopology
*/
GAIATOPO_DECLARE int gaiaReadTopologyFromDBMS (sqlite3 *
handle,
const char
*topo_name,
char **topology_name,
int *srid,
double *tolerance,
int *has_z);
/**
retrieves an already defined opaque Topology Accessor object from the
internal connection cache
\param cache pointer to the opaque Cache Object supporting the DB connection
\param topo_name unique name identifying the Topology.
\return pointer to an already existing Topology Accessor Object: NULL on failure.
\sa gaiaTopologyCreate, gaiaTopologyDestroy, gaiaTopologyFromDBMS,
gaiaGetTopology
*/
GAIATOPO_DECLARE GaiaTopologyAccessorPtr gaiaTopologyFromCache (const void
*cache,
const char
*topo_name);
/**
will attempt to return a reference to a Topology Accessor object
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param topo_name unique name identifying the Topology.
\return pointer to Topology Accessor Object: NULL on failure.
\sa gaiaTopologyCreate, gaiaTopologyDestroy, gaiaTopologyFromCache,
gaiaTopologyFromDBMS
\note if a corresponding Topology Accessor Object is already defined
will return a pointer to such Objet. Otherwise an attempt will be made
in order to create a new Topology Accessor object starting from its DB
configuration.
*/
GAIATOPO_DECLARE GaiaTopologyAccessorPtr gaiaGetTopology (sqlite3 *
handle,
const void
*cache,
const char
*topo_name);
/**
destroys a Topology Accessor object and any related memory allocation
\param ptr pointer to the Topology Accessor Object to be destroyed.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE void gaiaTopologyDestroy (GaiaTopologyAccessorPtr ptr);
/**
Adds an isolated node into the Topology
\param ptr pointer to the Topology Accessor Object.
\param face the unique identifier of containing face or -1 for "unknown".
\param pt pointer to the Node Geometry.
\param skip_checks boolean: if TRUE skips consistency checks
(coincident nodes, crossing edges, actual face containement)
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaAddIsoNode (GaiaTopologyAccessorPtr
ptr, sqlite3_int64 face,
gaiaPointPtr pt,
int skip_checks);
/**
Moves an isolated node in a Topology from one point to another
\param ptr pointer to the Topology Accessor Object.
\param node the unique identifier of node.
\param pt pointer to the Node Geometry.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int gaiaMoveIsoNode (GaiaTopologyAccessorPtr ptr,
sqlite3_int64 node, gaiaPointPtr pt);
/**
Removes an isolated node from a Topology
\param ptr pointer to the Topology Accessor Object.
\param node the unique identifier of node.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int gaiaRemIsoNode (GaiaTopologyAccessorPtr ptr,
sqlite3_int64 node);
/**
Adds an isolated edge into the Topology
\param ptr pointer to the Topology Accessor Object.
\param start_node the Start Node's unique identifier.
\param end_node the End Node unique identifier.
\param ln pointer to the Edge Geometry.
\return the ID of the inserted Edge; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaAddIsoEdge (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64 start_node,
sqlite3_int64 end_node,
gaiaLinestringPtr ln);
/**
Removes an isolated edge from a Topology
\param ptr pointer to the Topology Accessor Object.
\param edge the unique identifier of edge.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int gaiaRemIsoEdge (GaiaTopologyAccessorPtr ptr,
sqlite3_int64 edge);
/**
Changes the shape of an Edge without affecting the Topology structure
\param ptr pointer to the Topology Accessor Object.
\param edge_id the Edge unique identifier.
\param ln pointer to the Edge Geometry.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int gaiaChangeEdgeGeom (GaiaTopologyAccessorPtr ptr,
sqlite3_int64 edge_id,
gaiaLinestringPtr ln);
/**
Split an edge by a node, modifying the original edge and adding a new one.
\param ptr pointer to the Topology Accessor Object.
\param edge the unique identifier of the edge to be split.
\param pt pointer to the Node Geometry.
\param skip_checks boolean: if TRUE skips consistency checks
(coincident node, point not on edge...)
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaModEdgeSplit (GaiaTopologyAccessorPtr
ptr, sqlite3_int64 edge,
gaiaPointPtr pt,
int skip_checks);
/**
Split an edge by a node, replacing it with two new edges.
\param ptr pointer to the Topology Accessor Object.
\param edge the unique identifier of the edge to be split.
\param pt pointer to the Node Geometry.
\param skip_checks boolean: if TRUE skips consistency checks
(coincident node, point not on edge...)
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaNewEdgesSplit (GaiaTopologyAccessorPtr
ptr, sqlite3_int64 edge,
gaiaPointPtr pt,
int skip_checks);
/**
Adds a new edge possibly splitting and modifying a face.
\param ptr pointer to the Topology Accessor Object.
\param start_node the unique identifier of the starting node.
\param end_node the unique identifier of the ending node.
\param ln pointer to the Edge Geometry.
\param skip_checks boolean: if TRUE skips consistency checks
(curve being simple and valid, start/end nodes, consistency
actual face containement)
\return the ID of the inserted Edge; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaAddEdgeModFace (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64
start_node,
sqlite3_int64 end_node,
gaiaLinestringPtr ln,
int skip_checks);
/**
Adds a new edge possibly splitting a face (replacing with two new faces).
\param ptr pointer to the Topology Accessor Object.
\param start_node the unique identifier of the starting node.
\param end_node the unique identifier of the ending node.
\param ln pointer to the Edge Geometry.
\param skip_checks boolean: if TRUE skips consistency checks
(curve being simple and valid, start/end nodes, consistency
actual face containement)
\return the ID of the inserted Edge; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64
gaiaAddEdgeNewFaces (GaiaTopologyAccessorPtr ptr,
sqlite3_int64 start_node, sqlite3_int64 end_node,
gaiaLinestringPtr ln, int skip_checks);
/**
Removes an edge, and if the removed edge separated two faces, delete one
of them and modify the other to take the space of both.
\param ptr pointer to the Topology Accessor Object.
\param edge_id the unique identifier of the edge to be removed.
\return the ID of face that takes up the space previously occupied
by the removed edge; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaRemEdgeModFace (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64 edge_id);
/**
Removes an edge, and if the removed edge separated two faces, delete the
original faces and replace them with a new face.
\param ptr pointer to the Topology Accessor Object.
\param edge_id the unique identifier of the edge to be removed.
\return the ID of the created face; a negative number on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaRemEdgeNewFace (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64 edge_id);
/**
Heal two edges by removing the node connecting them, modifying the
first edge and removing the second edge
\param ptr pointer to the Topology Accessor Object.
\param edge_id1 the unique identifier of the first edge to be healed.
\param edge_id2 the unique identifier of the second edge to be healed.
\return the ID of the removed node.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaModEdgeHeal (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64 edge_id1,
sqlite3_int64 edge_id2);
/**
Heal two edges by removing the node connecting them, deleting both edges
and replacing them with an edge whose orientation is the same of the
first edge provided
\param ptr pointer to the Topology Accessor Object.
\param edge_id1 the unique identifier of the first edge to be healed.
\param edge_id2 the unique identifier of the second edge to be healed.
\return the ID of the removed node.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64 gaiaNewEdgeHeal (GaiaTopologyAccessorPtr
ptr,
sqlite3_int64 edge_id1,
sqlite3_int64 edge_id2);
/**
Return the geometry of a Topology Face
\param ptr pointer to the Topology Accessor Object.
\param face the unique identifier of the face.
\return pointer to Geometry (polygon); NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaGetFaceGeometry (GaiaTopologyAccessorPtr ptr, sqlite3_int64 face);
/**
Updates a temporary table containing the ordered list of Edges
(in counterclockwise order) for every Face.
EdgeIDs are signed value; a negative ID intends reverse direction.
\param ptr pointer to the Topology Accessor Object.
\param face the unique identifier of the face.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaGetFaceEdges (GaiaTopologyAccessorPtr ptr, sqlite3_int64 face);
/**
Find the ID of a Node at a Point location
\param ptr pointer to the Topology Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of a Node; -1 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64
gaiaGetNodeByPoint (GaiaTopologyAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Find the ID of an Edge at a Point location
\param ptr pointer to the Topology Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of an Edge; -1 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64
gaiaGetEdgeByPoint (GaiaTopologyAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Find the ID of a Face at a Point location
\param ptr pointer to the Topology Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of a Face; -1 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64
gaiaGetFaceByPoint (GaiaTopologyAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Transforms a (multi)Linestring or (multi)Polygon into an new MultiLinestring.
\param geom pointer to the input Geometry (Linestring, MultiLinestring,
Polygon or MultiPolygon).
\param line_max_points if set to a positive number all input Linestrings
and/or Polygon Rings will be split into simpler Lines having no more than
this maximum number of points.
\param max_length if set to a positive value all input Linestrings
and/or Polygon Rings will be split into simpler Lines having a length
not exceeding this threshold. If both line_max_points and max_legth
are set as the same time the first condition occurring will cause
a new Line to be started.
\return a MultiLinestring Geometry; NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaTopoGeo_SubdivideLines (gaiaGeomCollPtr geom, int line_max_points,
double max_length);
/**
Adds a Point to an existing Topology and possibly splitting an Edge.
\param ptr pointer to the Topology Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of the Node; -1 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE sqlite3_int64
gaiaTopoGeo_AddPoint (GaiaTopologyAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Adds a Linestring to an existing Topology without determining generated faces..
\param ptr pointer to the Topology Accessor Object.
\param ln pointer to the Linestring Geometry.
\param tolerance approximation factor.
\param edge_ids on success will point to an array of Edge IDs
\param ids_count on success will report the number of Edge IDs in the
above array
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_AddLineStringNoFace
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_AddLineString (GaiaTopologyAccessorPtr ptr,
gaiaLinestringPtr pt, double tolerance,
sqlite3_int64 ** edge_ids, int *ids_count);
/**
Adds a Linestring to an existing Topology and possibly splitting Edges/Faces.
\param ptr pointer to the Topology Accessor Object.
\param ln pointer to the Linestring Geometry.
\param tolerance approximation factor.
\param edge_ids on success will point to an array of Edge IDs
\param ids_count on success will report the number of Edge IDs in the
above array
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_AddLineString, gaiaTopoGeo_Polygonize
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_AddLineStringNoFace (GaiaTopologyAccessorPtr ptr,
gaiaLinestringPtr pt,
double tolerance,
sqlite3_int64 ** edge_ids,
int *ids_count);
/**
Determine and register all topology faces.
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_AddLineStringNoFace,
gaiaTopoGeo_FromGeoTableNoFace, FromGeoTableNoFaceExt
*/
GAIATOPO_DECLARE int gaiaTopoGeo_Polygonize (GaiaTopologyAccessorPtr ptr);
/**
Snap Geometry to Topology.
\param ptr pointer to the Topology Accessor Object.
\param geom pointer to the input Geometry.
\param tolerance_snap snap tolerance.
\param tolerance_removal removal tolerance (use -1 to skip removal phase).
\param iterate if non zero, allows snapping to more than a single
vertex, iteratively.
\return pointer to the snapped Geometry; NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaTopoSnap (GaiaTopologyAccessorPtr ptr, gaiaGeomCollPtr geom,
double tolerance_snap, double tolerance_removal,
int iterate);
/**
Adds a Polygon to an existing Topology and possibly splitting Edges/Faces.
\param ptr pointer to the Topology Accessor Object.
\param pg pointer to the Polygon Geometry.
\param tolerance approximation factor.
\param face_ids on success will point to an array of Face IDs
\param ids_count on success will report the number of Face IDs in the
above array
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_AddPolygon (GaiaTopologyAccessorPtr ptr,
gaiaPolygonPtr pg, double tolerance,
sqlite3_int64 ** face_ids, int *ids_count);
/**
Populates a Topology by importing a whole GeoTable
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the input GeoTable.
If NULL the "main" DB will be intended by default.
\param table name of the input GeoTable.
\param column name of the input Geometry Column.
Could be NULL is the input table has just a single Geometry Column.
\param tolerance approximation factor.
\param line_max_points if set to a positive number all input Linestrings
and/or Polygon Rings will be split into simpler Linestrings having no more
than this maximum number of points.
\param max_length if set to a positive value all input Linestrings
and/or Polygon Rings will be split into simpler Lines having a length
not exceeding this threshold. If both line_max_points and max_legth
are set as the same time the first condition occurring will cause
a new Line to be started.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_FromGeoTableNoFace
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_FromGeoTable (GaiaTopologyAccessorPtr ptr,
const char *db_prefix, const char *table,
const char *column, double tolerance,
int line_max_points, double max_length);
/**
Populates a Topology by importing a whole GeoTable without
determining generated faces
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the input GeoTable.
If NULL the "main" DB will be intended by default.
\param table name of the input GeoTable.
\param column name of the input Geometry Column.
Could be NULL is the input table has just a single Geometry Column.
\param tolerance approximation factor.
\param line_max_points if set to a positive number all input Linestrings
and/or Polygon Rings will be split into simpler Linestrings having no more
than this maximum number of points.
\param max_length if set to a positive value all input Linestrings
and/or Polygon Rings will be split into simpler Lines having a length
not exceeding this threshold. If both line_max_points and max_legth
are set as the same time the first condition occurring will cause
a new Line to be started.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_FromGeoTable, gaiaTopoGeo_Polygonize
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_FromGeoTableNoFace (GaiaTopologyAccessorPtr ptr,
const char *db_prefix,
const char *table, const char *column,
double tolerance, int line_max_points,
double max_length);
/**
Populates a Topology by importing a whole GeoTable - Extended mode
\param ptr pointer to the Topology Accessor Object.
\param sql_in an SQL statement (SELECT) returning input features
\param sql_out a second SQL statement (INSERT INTO) intended to
store failing features references into the "dustbin" table.
\param sql_in2 an SQL statement (SELECT) returning a single input
feature (used for retrying to insert a failing feature)
\param tolerance approximation factor.
\param line_max_points if set to a positive number all input Linestrings
and/or Polygon Rings will be split into simpler Linestrings having no more
than this maximum number of points.
\param max_length if set to a positive value all input Linestrings
and/or Polygon Rings will be split into simpler Lines having a length
not exceeding this threshold. If both line_max_points and max_legth
are set as the same time the first condition occurring will cause
a new Line to be started.
\return 0 if all input features were succesfully importer, or a
positive number (total count of failing features raising an exception
and referenced by the "dustbin" table); -1 if some unexpected
error occurred.
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_FromGeoTableNoFaceExtended
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_FromGeoTableExtended (GaiaTopologyAccessorPtr ptr,
const char *sql_in,
const char *sql_out,
const char *sql_in2,
double tolerance,
int line_max_points,
double max_length);
/**
Populates a Topology by importing a whole GeoTable without
determining generated faces - Extended mode
\param ptr pointer to the Topology Accessor Object.
\param sql_in an SQL statement (SELECT) returning input features
\param sql_out a second SQL statement (INSERT INTO) intended to
store failing features references into the "dustbin" table.
\param sql_in2 an SQL statement (SELECT) returning a single input
feature (used for retrying to insert a failing feature)
\param tolerance approximation factor.
\param line_max_points if set to a positive number all input Linestrings
and/or Polygon Rings will be split into simpler Linestrings having no more
than this maximum number of points.
\param max_length if set to a positive value all input Linestrings
and/or Polygon Rings will be split into simpler Lines having a length
not exceeding this threshold. If both line_max_points and max_legth
are set as the same time the first condition occurring will cause
a new Line to be started.
\return 0 if all input features were succesfully importer, or a
positive number (total count of failing features raising an exception
and referenced by the "dustbin" table); -1 if some unexpected
error occurred.
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_FromGeoTableExtended,
gaiaTopoGeo_Polygonize
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_FromGeoTableNoFaceExtended (GaiaTopologyAccessorPtr ptr,
const char *sql_in,
const char *sql_out,
const char *sql_in2,
double tolerance,
int line_max_points,
double max_length);
/**
Creates and populates a new GeoTable by snapping all Geometries
contained into another GeoTable against a given Topology
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the input GeoTable.
If NULL the "main" DB will be intended by default.
\param table name of the input GeoTable.
\param column name of the input Geometry Column.
Could be NULL is the input table has just a single Geometry Column.
\param outtable name of the output GeoTable.
\param tolerance_snap snap tolerance.
\param tolerance_removal removal tolerance (use -1 to skip removal phase).
\param iterate if non zero, allows snapping to more than a single
vertex, iteratively.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_SnappedGeoTable (GaiaTopologyAccessorPtr ptr,
const char *db_prefix, const char *table,
const char *column, const char *outtable,
double tolerance_snap,
double tolerance_removal, int iterate);
/**
Creates a temporary table containing a validation report for a given TopoGeo.
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int gaiaValidateTopoGeo (GaiaTopologyAccessorPtr ptr);
/**
Return a Point geometry (seed) identifying a Topology Edge
\param ptr pointer to the Topology Accessor Object.
\param edge the unique identifier of the edge.
\return pointer to Geometry (point); NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaGetEdgeSeed (GaiaTopologyAccessorPtr ptr, sqlite3_int64 edge);
/**
Return a Point geometry (seed) identifying a Topology Face
\param ptr pointer to the Topology Accessor Object.
\param face the unique identifier of the face.
\return pointer to Geometry (point); NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaGetFaceSeed (GaiaTopologyAccessorPtr ptr, sqlite3_int64 face);
/**
Ensures that all Edges on a Topology-Geometry will have not less
than three vertices; for all Edges found being simple two-points
segments a third intermediate point will be interpolated.
\param ptr pointer to the Topology Accessor Object.
\return the total number of changed Edges; a negativa number on error
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_DisambiguateSegmentEdges (GaiaTopologyAccessorPtr ptr);
/**
Will update all Seeds for a Topology-Geometry
\param ptr pointer to the Topology Accessor Object.
\param mode if set to 0 a full update of all Seeds will be performed,
otherwise an incremental update will happen.
\return 1 on success; 0 on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeoUpdateSeeds (GaiaTopologyAccessorPtr ptr, int mode);
/**
Will snap a Point geometry to TopoSeeds
\param ptr pointer to the Topology Accessor Object.
\param pt pointer to the Point Geometry.
\param distance tolerance approximation factor.
\return pointer to Geometry (point); NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaTopoGeoSnapPointToSeed (GaiaTopologyAccessorPtr ptr,
gaiaGeomCollPtr pt, double distance);
/**
Will snap a Linestring geometry to TopoSeeds
\param ptr pointer to the Topology Accessor Object.
\param ln pointer to the Linestring Geometry.
\param distance tolerance approximation factor.
\return pointer to Geometry (linestring); NULL on failure.
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE gaiaGeomCollPtr
gaiaTopoGeoSnapLinestringToSeed (GaiaTopologyAccessorPtr ptr,
gaiaGeomCollPtr ln, double distance);
/**
Extracts a Simple Features Table out from a Topology by matching
Topology Seeds to a given reference Table.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output output table to be created and populated.
\param with_spatial_index boolean flag: if set to TRUE (non ZERO) a Spatial
Index supporting the output table will be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_ToGeoTable (GaiaTopologyAccessorPtr ptr,
const char *db_prefix, const char *ref_table,
const char *ref_column, const char *out_table,
int with_spatial_index);
/**
Creates and populates a Table containing a comprehensive report
about all intesections between the Faces of some Topology and
a given reference Table of the Polygon/Multipolygon type.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output output table to be created and populated.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_PolyFacesList (GaiaTopologyAccessorPtr ptr,
const char *db_prefix, const char *ref_table,
const char *ref_column,
const char *out_table);
/**
Creates and populates a Table containing a comprehensive report
about all intesections between the Edges of some Topology and
a given reference Table of the Linestring/Multilinestring type.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output output table to be created and populated.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_LineEdgesList (GaiaTopologyAccessorPtr ptr,
const char *db_prefix, const char *ref_table,
const char *ref_column,
const char *out_table);
/**
Extracts a simplified/generalized Simple Features Table out from a Topology
by matching Topology Seeds to a given reference Table.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output output table to be created and populated.
\param tolerance approximation radius required by the Douglar-Peucker
simplification algorithm.
\param with_spatial_index boolean flag: if set to TRUE (non ZERO) a Spatial
Index supporting the output table will be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_ToGeoTableGeneralize (GaiaTopologyAccessorPtr ptr,
const char *db_prefix,
const char *ref_table,
const char *ref_column,
const char *out_table,
double tolerance,
int with_spatial_index);
/**
Removes all small Faces from a Topology
\param ptr pointer to the Topology Accessor Object.
\param min_circularity threshold Circularity-index identifying threadlike Faces.
\param min_area threshold area to identify small Faces.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_RemoveSmallFaces (GaiaTopologyAccessorPtr ptr,
double min_circularity, double min_area);
/**
Removes all dangling Edges from a Topology
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_RemoveDanglingEdges (GaiaTopologyAccessorPtr ptr);
/**
Removes all dangling Nodes from a Topology
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_RemoveDanglingNodes (GaiaTopologyAccessorPtr ptr);
/**
Removes all useless Nodes from a Topology by calling ST_NewEdgeHeal
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_ModEdgeHeal
*/
GAIATOPO_DECLARE int gaiaTopoGeo_NewEdgeHeal (GaiaTopologyAccessorPtr ptr);
/**
Removes all useless Nodes from a Topology by calling ST_ModEdgeHeal
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_NewEdgeHeal
*/
GAIATOPO_DECLARE int gaiaTopoGeo_ModEdgeHeal (GaiaTopologyAccessorPtr ptr);
/**
Removes all useless Nodes from a Topology by calling ST_NewEdgeHeal
\param ptr pointer to the Topology Accessor Object.
\param line_max_points if set to a positive number all input Edges
will be split into simpler Edges having no more than this maximum
number of points.
\param max_length if set to a positive value all input Edges will
be split into simpler Edges having a length not exceeding this
threshold. If both line_max_points and max_legth are set as the
same time the first condition occurring will cause an Edge to be split
in two halves.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_ModEdgeHeal
*/
GAIATOPO_DECLARE int gaiaTopoGeo_NewEdgesSplit (GaiaTopologyAccessorPtr ptr,
int line_max_points,
double max_length);
/**
Removes all useless Nodes from a Topology by calling ST_ModEdgeHeal
\param ptr pointer to the Topology Accessor Object.
\param line_max_points if set to a positive number all input Edges
will be split into simpler Edges having no more than this maximum
number of points.
\param max_length if set to a positive value all input Edges will
be split into simpler Edges having a length not exceeding this
threshold. If both line_max_points and max_legth are set as the
same time the first condition occurring will cause an Edge to be split
in two halves.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS, gaiaTopoGeo_NewEdgeHeal
*/
GAIATOPO_DECLARE int gaiaTopoGeo_ModEdgeSplit (GaiaTopologyAccessorPtr ptr,
int line_max_points,
double max_length);
/**
creates a TopoLayer and its corresponding Feature relations for a given
Topology by matching Topology Seeds to a given reference Table.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param topolayer_name name of the TopoLayer to be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_CreateTopoLayer (GaiaTopologyAccessorPtr ptr,
const char *db_prefix,
const char *ref_table,
const char *ref_column,
const char *topolayer_name);
/**
initializes a TopoLayer (laking all corresponding Feature relations) for a given
Topology from a given reference Table.
\param ptr pointer to the Topology Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param topolayer_name name of the TopoLayer to be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_InitTopoLayer (GaiaTopologyAccessorPtr ptr,
const char *db_prefix,
const char *ref_table,
const char *topolayer_name);
/**
completely removes a TopoLayer from a Topology.
\param ptr pointer to the Topology Accessor Object.
\param topolayer_name name of the TopoLayer to be removed.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_RemoveTopoLayer (GaiaTopologyAccessorPtr ptr,
const char *topolayer_name);
/**
creates a GeoTable by exporting Features out from a given TopoLayer.
\param ptr pointer to the Topology Accessor Object.
\param topolayer_name name of an existing TopoLayer.
\param out_table name of the output GeoTable to be created.
\param with_spatial_index boolean flag: if set to TRUE (non ZERO) a Spatial
Index supporting the output table will be created.
\param create_only boolean flag; is set to any value != 0 (TRUE)
just the output table will be creayed but no TopoFeature will
be actually inserted.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_ExportTopoLayer (GaiaTopologyAccessorPtr ptr,
const char *topolayer_name,
const char *out_table,
int with_spatial_index, int create_only);
/**
inserts into the output GeoTable a single Features extracted out
from a given TopoLayer.
\param ptr pointer to the Topology Accessor Object.
\param topolayer_name name of an existing TopoLayer.
\param out_table name of the target GeoTable.
\param fid unique identifier of the TopoLayer's Feature to
be inserted.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaTopologyFromDBMS
*/
GAIATOPO_DECLARE int
gaiaTopoGeo_InsertFeatureFromTopoLayer (GaiaTopologyAccessorPtr ptr,
const char *topolayer_name,
const char *out_table,
sqlite3_int64 fid);
#ifdef __cplusplus
}
#endif
#endif /* _GAIATOPO_H */
libspatialite-5.1.0/src/headers/spatialite/gaia_network.h 0000644 0001750 0001750 00000050211 14463127014 020451 0000000 0000000 /*
gaia_network.h -- Gaia common support for Topology-Network
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2015-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gaia_network.h
Topology-Network handling functions and constants
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* stdio.h included for FILE objects. */
#include
#ifdef DLL_EXPORT
#define GAIANET_DECLARE __declspec(dllexport)
#else
#define GAIANET_DECLARE extern
#endif
#endif
#ifndef _GAIANET_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIANET_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
Typedef for Topology-Network Accessor Object (opaque, hidden)
\sa GaiaNetworkAccessorPtr
*/
typedef struct gaia_network_accessor GaiaNetworkAccessor;
/**
Typedef for Network Accessor Object pointer (opaque, hidden)
\sa GaiaNetworkAccessor
*/
typedef struct gaia_network_accessor *GaiaNetworkAccessorPtr;
/**
returns the last Topology-Network exception (if any)
\param network_name unique name identifying the Topology-Network.
\return pointer to the last Topology-Network error message: may be NULL if
no Topology error is currently pending.
*/
GAIANET_DECLARE const char *gaiaNetworkGetLastException (const char
*network_name);
/**
creates a new Topology-Network and all related DB objects
\param handle pointer to the current DB connection.
\param network_name unique name identifying the Topology-Network.
\param spatial boolean: if TRUE this Topology-Network will be assumed
to be of the Spatial type, otherwise a Logical Network will be assumed.
\param srid a spatial reference identifier (only applies to Spatial
Networks).
\param has_z boolean: if TRUE this Topology-Network supports 3D (XYZ)
(only applies to Spatial Networks).
\param allow_coincident boolean: if TRUE coincident Nodes will be
tolerated, otherwise a coincident Node condition will raise an exception.
This argument only applies to Spatial Networks and is meaningless for
Logical Networks.
\return 0 on failure: any other value on success.
\sa gaiaNetworkDrop
*/
GAIANET_DECLARE int gaiaNetworkCreate (sqlite3 * handle,
const char *network_name,
int spatial, int srid, int has_z,
int allow_coincident);
/**
completely drops an already existing Topology-Network and removes all related DB objects
\param handle pointer to the current DB connection.
\param network_name unique name identifying the Topology-Network.
\return 0 on failure: any other value on success.
\sa gaiaNetworkCreate
*/
GAIANET_DECLARE int gaiaNetworkDrop (sqlite3 * handle,
const char *network_name);
/**
creates an opaque Topology-Network Accessor object starting from its DB configuration
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param network_name unique name identifying the Topology-Network.
\return the pointer to newly created Topology-Network Accessor Object:
NULL on failure.
\sa gaiaNetworkCreate, gaiaNetworkDestroy, gaiaNetworkFromCache,
gaiaGetNetwork
\note you are responsible to destroy (before or after) any allocated
Topology-Network Accessor Object. The Topology-Network Accessor once
created will be preserved within the internal connection cache for
future references.
*/
GAIANET_DECLARE GaiaNetworkAccessorPtr gaiaNetworkFromDBMS (sqlite3 *
handle,
const void
*cache,
const char
*network_name);
/**
retrieves a Topology configuration from DB
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param net_name unique name identifying the Topology-Network.
\param network_name on completion will point to the real Topology-Network name.
\param spatial on completion will report if the Topology-Network is of
the Spatial or Logical type.
\param srid on completion will contain the Topology-Network SRID.
\param has_z on completion will report if the Topology-Network is of the 3D type.
\param allow_coincident on completion will report if the Topology-Network
tolerates a Coindident Nodes condition without raising an exception.
\return 1 on success: NULL on failure.
\sa gaiaNetworkCreate, gaiaNetworkDestroy, gaiaNetworkFromCache,
gaiaGetNetwork
*/
GAIANET_DECLARE int gaiaReadNetworkFromDBMS (sqlite3 *
handle,
const char
*net_name,
char **network_name,
int *spatial, int *srid,
int *has_z,
int *allow_coincident);
/**
retrieves an already defined opaque Topology-Network Accessor object from the
internal connection cache
\param cache pointer to the opaque Cache Object supporting the DB connection
\param network_name unique name identifying the Topology-Network.
\return pointer to an already existing Topology-Network Accessor Object: NULL on failure.
\sa gaiaNetworkCreate, gaiaNetworkDestroy, gaiaNetworkFromDBMS,
gaiaGetNetwork
*/
GAIANET_DECLARE GaiaNetworkAccessorPtr gaiaNetworkFromCache (const void
*cache,
const char
*network_name);
/**
will attempt to return a reference to a Topology-Network Accessor object
\param handle pointer to the current DB connection.
\param cache pointer to the opaque Cache Object supporting the DB connection
\param network_name unique name identifying the Topology-Network.
\return pointer to Topology-Network Accessor Object: NULL on failure.
\sa gaiaNetworkCreate, gaiaNetworkDestroy, gaiaNetworkFromCache,
gaiaNetworkFromDBMS
\note if a corresponding Topology-Network Accessor Object is already defined
will return a pointer to such Objet. Otherwise an attempt will be made
in order to create a new Topology-Network Accessor object starting from
its DB configuration.
*/
GAIANET_DECLARE GaiaNetworkAccessorPtr gaiaGetNetwork (sqlite3 *
handle,
const void
*cache,
const char
*network_name);
/**
destroys a Topology-Network Accessor object and any related memory allocation
\param ptr pointer to the Topology-Network Accessor Object to be destroyed.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE void gaiaNetworkDestroy (GaiaNetworkAccessorPtr ptr);
/**
Adds an isolated node into the Topology-Network
\param ptr pointer to the Topology-Network Accessor Object.
\param pt pointer to the Node Geometry.
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaMoveIsoNetNode, gaiaRemIsoNetNode,
gaiaAddLink
*/
GAIANET_DECLARE sqlite3_int64 gaiaAddIsoNetNode (GaiaNetworkAccessorPtr
ptr, gaiaPointPtr pt);
/**
Moves an isolated node in a Topology-Network from one point to another
\param ptr pointer to the Topology-Network Accessor Object.
\param node the unique identifier of node.
\param pt pointer to the Node Geometry.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS, gaiaAddIsoNetNode, gaiaRemIsoNetNode
*/
GAIANET_DECLARE int gaiaMoveIsoNetNode (GaiaNetworkAccessorPtr ptr,
sqlite3_int64 node,
gaiaPointPtr pt);
/**
Removes an isolated node from a Topology-Network
\param ptr pointer to the Topology-Network Accessor Object.
\param node the unique identifier of node.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS, gaiaAddIsoNetNode, gaiaMoveIsoNetNode
*/
GAIANET_DECLARE int gaiaRemIsoNetNode (GaiaNetworkAccessorPtr ptr,
sqlite3_int64 node);
/**
Adds a link into the Topology-Network
\param ptr pointer to the Topology-Network Accessor Object.
\param start_node the Start Node's unique identifier.
\param end_node the End Node unique identifier.
\param ln pointer to the Link Geometry.
\return the ID of the inserted Link; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddIsoNetNode, gaiaChangeLinkGeom,
gaiaRemoveLink, gaiaNewLogLinkSplit, gaiaModLogLinkSplit,
gaiaNewGeoLinkSplit, gaiaModGeoLinkSplit, gaiaNewLinkHeal,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaAddLink (GaiaNetworkAccessorPtr ptr,
sqlite3_int64 start_node,
sqlite3_int64 end_node,
gaiaLinestringPtr ln);
/**
Changes the shape of a Link without affecting the Topology-Network structure
\param ptr pointer to the Topology-Network Accessor Object.
\param link_id the Link unique identifier.
\param ln pointer to the Link Geometry.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaRemoveLink
*/
GAIANET_DECLARE int gaiaChangeLinkGeom (GaiaNetworkAccessorPtr ptr,
sqlite3_int64 link_id,
gaiaLinestringPtr ln);
/**
Removes a Link from a Topology-Network
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of link.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink
*/
GAIANET_DECLARE int gaiaRemoveLink (GaiaNetworkAccessorPtr ptr,
sqlite3_int64 link);
/**
Split a logical link, replacing it with two new links.
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the link to be split.
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaModLogLinkSplit,
gaiaNewGeoLinkSplit, gaiaModGeoLinkSplit, gaiaNewLinkHeal,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaNewLogLinkSplit (GaiaNetworkAccessorPtr
ptr, sqlite3_int64 link);
/**
Split a logical link, modifying the original link and adding a new one.
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the link to be split.
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaNewLogLinkSplit,
gaiaNewGeoLinkSplit, gaiaModGeoLinkSplit, gaiaNewLinkHeal,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaModLogLinkSplit (GaiaNetworkAccessorPtr
ptr, sqlite3_int64 link);
/**
Split a spatial link by a node, replacing it with two new links.
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the link to be split.
\param pt pointer to the Node Geometry.
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaNewLogLinkSplit,
gaiaModLogLinkSplit, gaiaModGeoLinkSplit, gaiaNewLinkHeal,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaNewGeoLinkSplit (GaiaNetworkAccessorPtr
ptr,
sqlite3_int64 link,
gaiaPointPtr pt);
/**
Split a spatial link by a node, modifying the original link and adding
a new one.
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the link to be split.
\param pt pointer to the Node Geometry.
\return the ID of the inserted Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaNewLogLinkSplit,
gaiaModLogLinkSplit, gaiaNewGeoLinkSplit, gaiaNewLinkHeal,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaModGeoLinkSplit (GaiaNetworkAccessorPtr
ptr,
sqlite3_int64 link,
gaiaPointPtr pt);
/**
Heal two links by deleting the node connecting them, deleting both links,
and replacing them with a new link whose direction is the same as the
first link provided.
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the first link to be healed.
\param anotherlink the unique identifier of the second link to be healed.
\return the ID of the removed Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaNewLogLinkSplit,
gaiaModLogLinkSplit, gaiaNewGeoLinkSplit, gaiaModGeoLinkSplit,
gaiaModLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaNewLinkHeal (GaiaNetworkAccessorPtr
ptr, sqlite3_int64 link,
sqlite3_int64 anotherlink);
/**
Heal two links by deleting the node connecting them, modfying the first
link provided, and deleting the second link.
*
\param ptr pointer to the Topology-Network Accessor Object.
\param link the unique identifier of the first link to be healed.
\param anotherlink the unique identifier of the second link to be healed.
\return the ID of the removed Node; a negative number on failure.
\sa gaiaNetworkFromDBMS, gaiaAddLink, gaiaNewLogLinkSplit,
gaiaModLogLinkSplit, gaiaNewGeoLinkSplit, gaiaModGeoLinkSplit,
gaiaNewLinkHeal
*/
GAIANET_DECLARE sqlite3_int64 gaiaModLinkHeal (GaiaNetworkAccessorPtr
ptr, sqlite3_int64 link,
sqlite3_int64 anotherlink);
/**
Creates a temporary table containing a validation report for a given
Logical TopoNet.
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int gaiaValidLogicalNet (GaiaNetworkAccessorPtr ptr);
/**
Creates a temporary table containing a validation report for a given
Spatial TopoNet.
\param ptr pointer to the Topology Accessor Object.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int gaiaValidSpatialNet (GaiaNetworkAccessorPtr ptr);
/**
Find the ID of a NetNode at a Point location
\param ptr pointer to the Topology-Network Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of a NetNode; -1 on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE sqlite3_int64
gaiaGetNetNodeByPoint (GaiaNetworkAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Find the ID of a Link at a Point location
\param ptr pointer to the Topology-Network Accessor Object.
\param pt pointer to the Point Geometry.
\param tolerance approximation factor.
\return the ID of a Link; -1 on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE sqlite3_int64
gaiaGetLinkByPoint (GaiaNetworkAccessorPtr ptr, gaiaPointPtr pt,
double tolerance);
/**
Populates a Network by importing a whole GeoTable
\param ptr pointer to the Network Accessor Object.
\param db-prefix prefix of the DB containing the input GeoTable.
If NULL the "main" DB will be intended by default.
\param table name of the input GeoTable.
\param column name of the input Geometry Column.
Could be NULL is the input table has just a single Geometry Column.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNet_FromGeoTable (GaiaNetworkAccessorPtr ptr,
const char *db_prefix, const char *table,
const char *column);
/**
Return a Point geometry (seed) identifying a Network Link
\param ptr pointer to the Network Accessor Object.
\param link the unique identifier of the link.
\return pointer to Geomtry (point); NULL on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE gaiaGeomCollPtr
gaiaGetLinkSeed (GaiaNetworkAccessorPtr ptr, sqlite3_int64 link);
/**
Ensures that all Links on a Topology-Network will have not less
than three vertices; for all Links found being simple two-points
segments a third intermediate point will be interpolated.
\param ptr pointer to the Network Accessor Object.
\return the total number of changed Links; a negativa number on error
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNet_DisambiguateSegmentLinks (GaiaNetworkAccessorPtr ptr);
/**
Will update all Seeds for a Topology-Network
\param ptr pointer to the Network Accessor Object.
\param mode if set to 0 a full update of all Seeds will be performed,
otherwise an incremental update will happen.
\return 1 on success; 0 on failure.
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNetUpdateSeeds (GaiaNetworkAccessorPtr ptr, int mode);
/**
Extracts a Simple Features Table out from a Network by matching
Network Seeds to a given reference Table.
\param ptr pointer to the Network Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output table to be created and populated.
\param with_spatial_index boolean flag: if set to TRUE (non ZERO) a Spatial
Index supporting the output table will be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNet_ToGeoTable (GaiaNetworkAccessorPtr ptr,
const char *db_prefix, const char *ref_table,
const char *ref_column, const char *out_table,
int with_spatial_index);
/**
Extracts a simplified/generalized Simple Features Table out from a Network
by matching Network Seeds to a given reference Table.
\param ptr pointer to the Network Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output table to be created and populated.
\param tolerance approximation radius required by the Douglar-Peucker
simplification algorithm.
\param with_spatial_index boolean flag: if set to TRUE (non ZERO) a Spatial
Index supporting the output table will be created.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNet_ToGeoTableGeneralize (GaiaNetworkAccessorPtr ptr,
const char *db_prefix,
const char *ref_table,
const char *ref_column,
const char *out_table,
double tolerance,
int with_spatial_index);
/**
Creates and populates a Table containing a comprehensive report
about all intesections between the Links of some Network and
a given reference Table of the Linestring/Multilinestring type.
\param ptr pointer to the Network Accessor Object.
\param db-prefix prefix of the DB containing the reference GeoTable.
If NULL the "main" DB will be intended by default.
\param ref_table name of the reference GeoTable.
\param ref_column name of the reference Geometry Column.
Could be NULL is the reference table has just a single Geometry Column.
\param out_table name of the output output table to be created and populated.
\return 1 on success; -1 on failure (will raise an exception).
\sa gaiaNetworkFromDBMS
*/
GAIANET_DECLARE int
gaiaTopoNet_LineLinksList (GaiaNetworkAccessorPtr ptr,
const char *db_prefix, const char *ref_table,
const char *ref_column,
const char *out_table);
#ifdef __cplusplus
}
#endif
#endif /* _GAIANET_H */
libspatialite-5.1.0/src/headers/spatialite/gg_sequence.h 0000644 0001750 0001750 00000012205 14463127014 020265 0000000 0000000 /*
gg_sequence.h -- Gaia support for Spatialite's own Sequence
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file gg_sequence.h
Spatialite's own Sequence
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* stdio.h included for FILE objects. */
#include
#ifdef DLL_EXPORT
#define GAIASEQ_DECLARE __declspec(dllexport)
#else
#define GAIASEQ_DECLARE extern
#endif
#endif
#ifndef _GG_SEQUENCE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_SEQUENCE_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
Typedef for Spatialite's own Sequence
*/
typedef struct gaia_sequence
{
/** name of the Sequence; NULL for the generic unnamed Sequence */
char *seq_name;
/** current value */
int value;
/** pointer to next Sequence (linked list) */
struct gaia_sequence *next;
} gaiaSequence;
/**
Typedef for Spatialite's own Sequence
*/
typedef gaiaSequence *gaiaSequencePtr;
/**
/ Creates a new SpatiaLite's own Sequence or retrieves an already
existing Sequence of the same name
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param seq_name name of the Sequence (may be NULL)
\return a pointer to the Sequence or NULL on failure
\sa gaiaFindSequence(), gaiaLastUsedSequence(), gaiaSequenceNext(),
gaiaResetSequence()
*/
GAIASEQ_DECLARE gaiaSequencePtr gaiaCreateSequence (const void *p_cache,
const char *seq_name);
/**
/ Finds an existing SpatiaLite's own Sequence
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param seq_name name of the Sequence (may be NULL)
\return a pointer to the Sequence or NULL on failure
\sa gaiaCreateSequence(), gaiaLastUsedSequence(), gaiaSequenceNext(),
gaiaResetSequence()
*/
GAIASEQ_DECLARE gaiaSequencePtr gaiaFindSequence (const void *p_cache,
const char *seq_name);
/**
/ Finds an existing SpatiaLite's own Sequence
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param last_value on sucess will contain the most recently used Sequence value
\return ZERO on failure, any other value on success.
\sa gaiaCreateSequence(), gaiaLastUsedSequence(), gaiaSequenceNext(),
gaiaResetSequence()
*/
GAIASEQ_DECLARE int gaiaLastUsedSequence (const void *p_cache,
int *last_value);
/**
/ Increases by 1 the value of some SpatiaLite's own Sequence
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param sequence a memory pointer returned by gaiaFindSequence() or
gaiaFindCreateSequence()
\param value new value to be set for the given Sequence
\return ZERO on failure, any other value on success.
\sa gaiaFindSequence(), gaiaCreateSequence(), gaiaLastUsedSequence(),
gaiaResetSequence()
\note this method will reset an existing Sequence. The initial
value will be increased by the next call to gaiaSequenceNext()
*/
GAIASEQ_DECLARE int gaiaSequenceNext (const void *p_cache,
gaiaSequencePtr sequence);
/**
/ Resets a SpatiaLite's own Sequence
\param sequence a memory pointer returned by gaiaFindSequence() or
gaiaCreateSequence()
\param value new value to be set for the given Sequence
\return ZERO on failure, any other value on success.
\sa gaiaFindSequence(), gaiaCreateSequence(), gaiaSequenceNext(),
gaiaLastUsedSequence()
\note this method will reset an existing Sequence. The initial
value will be increased by the next call to gaiaSequenceNext()
*/
GAIASEQ_DECLARE int gaiaResetSequence (gaiaSequencePtr sequence, int value);
#ifdef __cplusplus
}
#endif
#endif /* _GG_SEQUENCE_H */
libspatialite-5.1.0/src/headers/spatialite/stored_procedures.h 0000644 0001750 0001750 00000052601 14463127014 021537 0000000 0000000 /*
stored_procedues.h -- SQL Procedures and Stored Procedures functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2017-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file stored_procedures.h
SQL Procedures and Stored Procedures functions
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef DLL_EXPORT
#define SQLPROC_DECLARE __declspec(dllexport)
#else
#define SQLPROC_DECLARE extern
#endif
#endif
#ifndef _SQLPROC_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _SQLPROC_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constants */
/** SQL Procedure BLOB start marker */
#define SQLPROC_START 0xcd
/** SQL Procedure BLOB delimiter marker */
#define SQLPROC_DELIM 0x87
/** SQL Procedure BLOB stop marker */
#define SQLPROC_STOP 0xdc
/* data structures */
/**
SqlProc: Variable with value
*/
typedef struct gaiaSqlProc_VariableStruct
{
/** Variable Name */
char *Name;
/** Variable Value */
char *Value;
/** Pointer to next Variable (linked list) */
struct gaiaSqlProc_VariableStruct *Next;
} SqlProc_Variable;
/**
Typedef for SqlProc Variable structure
\sa SqlProc_VarList
*/
typedef SqlProc_Variable *SqlProc_VariablePtr;
/**
SqlProc: List of Variables with values
*/
typedef struct gaiaSqlProc_VarListStruct
{
/** invalid object */
int Error;
/** Error Message (if any) */
char *ErrMessage;
/** pointer to first Variable [linked list] */
SqlProc_VariablePtr First; /* Variables linked list - first */
/** pointer to last Variable [linked list] */
SqlProc_VariablePtr Last; /* Variables linked list - last */
} SqlProc_VarList;
/**
Typedef for SqlProc Variables List structure
\sa SqlProc_Variable
*/
typedef SqlProc_VarList *SqlProc_VarListPtr;
/* function prototypes */
/**
Return the most recent SQL Procedure error (if any)
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\return the most recent SQL Procedure error message (if any);
NULL in any other case.
*/
SQLPROC_DECLARE char *gaia_sql_proc_get_last_error (const void *p_cache);
/**
Will enable/disable a Logfile supporting Execute methods
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param filepath the pathname of the Logfile. NULL to disable logging.
\param append if TRUE the Logfile will be opened in append mode,
otherwise will be trucated.
\return 0 on failure, any other value on success.
\sa gaia_sql_proc_execute
*/
SQLPROC_DECLARE int gaia_sql_proc_logfile (const void *p_cache,
const char *filepath,
int append);
/**
Creates an empty list of Variables with Values
\return pointer to the Variables List
\sa gaia_sql_proc_destroy_variables, gaia_sql_proc_add_variable,
gaia_sql_proc_cooked_sql, gaia_sql_proc_execute
\note you are responsible to destroy (before or after) the Variables List
Object returned by this function by calling gaia_sql_proc_destroy_variables().
*/
SQLPROC_DECLARE SqlProc_VarListPtr gaia_sql_proc_create_variables ();
/**
Destroys a list of Variables with Values
\param list pointer to the Variables List Object to be destroyed.
\sa gaia_sql_proc_create_variables
*/
SQLPROC_DECLARE void
gaia_sql_proc_destroy_variables (SqlProc_VarListPtr list);
/**
Add a Variable with Value to the List
\param list pointer to the Variables List Object.
\param str text string expected to contain a Variable with Value
in the canonical form '@varname@=value'.
\return 0 on failure, any other value on success.
\sa gaia_sql_proc_create_variables, gaia_sql_proc_destroy_variables
*/
SQLPROC_DECLARE int
gaia_sql_proc_add_variable (SqlProc_VarListPtr list, const char *str);
/**
Builds a SQL Procedure BLOB object from Text
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param sql body of the SQL-script
\param charset the GNU ICONV name identifying the sql body charset
\param blob on succesfull completion this pointer will reference the
BLOB SQL Procedure Object (NULL on failure).
\param blob_sz on succesfull completion this pointer will reference
the size (in bytes) of the BLOB SQL Procedure Object.
\return 0 on failure, any other value on success.
\sa gaia_sql_proc_import, gaia_sql_proc_get_last_error,
gaia_sql_proc_is_valid, gaia_sql_proc_count,
gaia_sql_proc_variable, gaia_sql_proc_all_variables,
gaia_sql_proc_raw_sql, gaia_sql_proc_cooked_sql
\note you are responsible to free (before or after) the BLOB
SQL Procedure Object returned by this function.
*/
SQLPROC_DECLARE int gaia_sql_proc_parse (const void *cache,
const char *sql,
const char *charset,
unsigned char **blob,
int *blob_sz);
/**
Builds a SQL Procedure BLOB object from an external file
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param filepath path to the SQL-script to be loaded.
\param charset the GNU ICONV name identifying the sql body charset
\param blob on succesfull completion this pointer will reference the
BLOB SQL Procedure Object (NULL on failure).
\param blob_sz on succesfull completion this pointer will reference
the size (in bytes) of the BLOB SQL Procedure Object.
\return 0 on failure, any other value on success.
\sa gaia_sql_proc_parse, gaia_sql_proc_get_last_error
\note you are responsible to free (before or after) the BLOB
SQL Procedure Object returned by this function.
*/
SQLPROC_DECLARE int gaia_sql_proc_import (const void *cache,
const char *filepath,
const char *charset,
unsigned char **blob,
int *blob_sz);
/**
Checks if a BLOB is a valid SQL Procedure Object
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return 0 on failure: any other different value on success.
\sa gaia_sql_proc_parse
*/
SQLPROC_DECLARE int gaia_sql_proc_is_valid (const unsigned char
*blob, int blob_sz);
/**
Checks if a TEXT is a valid SQL Variable with Value
\param str the text string to be evaluated.
\return 0 on failure: any other different value on success.
*/
SQLPROC_DECLARE int gaia_sql_proc_is_valid_var_value (const char *str);
/**
Return the total count of Variables from a SQL Procedure Object
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return the total count of Variables or -1 on invalid Object
\sa gaia_sql_proc_parse, gaia_sql_proc_variable
*/
SQLPROC_DECLARE int gaia_sql_proc_var_count (const unsigned char
*blob, int blob_sz);
/**
Return the Name of the Nth Variable from a SQL Procedure Object
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\param index the first Variable has Index=0.
\return the name of the Nth Variable or NULL on invalid Object or
invalid Index.
\sa gaia_sql_proc_parse, gaia_sql_proc_var_count,
gaia_sql_proc_all_variables, gaia_sql_proc_raw_sql
\note you are responsible to free (before or after) the Variable Name
returned by this function.
*/
SQLPROC_DECLARE char *gaia_sql_proc_variable (const unsigned
char *blob,
int blob_sz, int index);
/**
Return the Names of all Variables from a SQL Procedure Object
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return a list of Variable Names separated by spaces or NULL on
invalid arguments.
\sa gaia_sql_proc_parse, gaia_sql_proc_var_count
\note you are responsible to free (before or after) the Variable Names
returned by this function.
*/
SQLPROC_DECLARE char *gaia_sql_proc_all_variables (const
unsigned char
*blob, int blob_sz);
/**
Return the raw SQL body from a SQL Procedure Object
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return the raw SQL body or NULL on invalid arguments.
\sa gaia_sql_proc_parse, gaia_sql_proc_var_count
\note you are responsible to free (before or after) the raw SQL body
returned by this function.
*/
SQLPROC_DECLARE char *gaia_sql_proc_raw_sql (const unsigned char
*blob, int blob_sz);
/**
Return a cooked SQL body from a raw SQL body by replacing Variable Values
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\param variables list of Variables with Values.
\param sql on succesfull completions will point to the "cooked" SQL body;
NULL on failure.
\return 0 on failure: any other different value on success.
\sa gaia_sql_proc_parse, gaia_sql_proc_var_count,
gaia_sql_proc_create_variables
\note you are responsible to free (before or after) the cooked SQL body
returned by this function.
*/
SQLPROC_DECLARE int gaia_sql_proc_cooked_sql (sqlite3 * handle,
const void *cache,
const unsigned char *blob,
int blob_sz,
SqlProc_VarListPtr variables,
char **sql);
/**
Will attempt to create the Stored Procedures Tables if not already existing
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_store, gaia_stored_proc_fetch,
gaia_stored_proc_delete, gaia_stored_proc_update_title,
gaia_stored_proc_update_sql, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_proc_create_tables (sqlite3 *
handle,
const void *cache);
/**
Permanently inserts a Stored Procedure into the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Procedure.
\param title short description of the Stored Procedure.
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_fetch,
gaia_stored_proc_delete, gaia_stored_proc_update_title,
gaia_stored_proc_update_sql, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_proc_store (sqlite3 * handle,
const void *cache,
const char *name,
const char *title,
const unsigned char
*blob, int blob_sz);
/**
Retrieves a permanent Stored Procedure from the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Procedure.
\param blob on succesfull completion this pointer will reference the
BLOB SQL Procedure Object (NULL on failure).
\param blob_sz on succesfull completion this pointer will reference
the size (in bytes) of the BLOB SQL Procedure Object.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_delete, gaia_stored_proc_update_title,
gaia_stored_proc_update_sql, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
\note you are responsible to free (before or after) the BLOB
SQL Procedure Object returned by this function.
*/
SQLPROC_DECLARE int gaia_stored_proc_fetch (sqlite3 * handle,
const void *cache,
const char *name,
unsigned char **blob,
int *blob_sz);
/**
Removes a permanent Stored Procedure from the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Procedure.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetche, gaia_stored_proc_update_title,
gaia_stored_proc_update_sql, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_proc_delete (sqlite3 * handle,
const void *cache,
const char *name);
/**
Updates the Title on a permanent Stored Procedure
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Procedure.
\param title short description of the Stored Procedure.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_sql, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_proc_update_title (sqlite3 *
handle,
const void
*cache,
const char
*name,
const char *title);
/**
Updates the Raw SQL Body on a permanent Stored Procedure
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Procedure.
\param blob pointer to the BLOB Object.
\param blob_sz size (in bytes) of the BLOB Object.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_var_store,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_proc_update_sql (sqlite3 *
handle,
const void
*cache,
const char
*name,
const
unsigned char
*blob, int blob_sz);
/**
Permanently inserts a Stored Variable into the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Variable.
\param title short description of the Stored Variable.
\param value the Variable Value in its textual representation.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_proc_update_sql,
gaia_stored_var_fetch, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_var_store (sqlite3 * handle,
const void *cache,
const char *name,
const char *title,
const char *value);
/**
Retrieves a Stored Variable from the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Variable.
\param var_with_val if set to TRUE value will point to a Variable with
Name string, otherwise (FALSE) it will point to a bare textual value.
\param value on succesfull completion this pointer will reference
the Stored Variable represented as a Variable with Value or as a bare
textual value depending on var_with_val setting.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_proc_update_sql,
gaia_stored_var_store, gaia_stored_var_delete,
gaia_stored_var_update_title, gaia_stored_var_update_value
\note you are responsible to free (before or after) the Text
String returned by this function.
*/
SQLPROC_DECLARE int gaia_stored_var_fetch (sqlite3 * handle,
const void *cache,
const char *name,
int var_with_val, char **value);
/**
Removes a Stored Variable from the DB
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Variable.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_proc_update_sql,
gaia_stored_var_store, gaia_stored_var_fetch,
gaia_stored_var_update_title, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_var_delete (sqlite3 * handle,
const void *cache,
const char *name);
/**
Updates the Title on a Stored Variable
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Variable.
\param title short description of the Stored Variable.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_proc_update_sql,
gaia_stored_var_store, gaia_stored_var_store, gaia_stored_var_fetch,
gaia_stored_var_delete, gaia_stored_var_update_value
*/
SQLPROC_DECLARE int gaia_stored_var_update_title (sqlite3 *
handle,
const void
*cache,
const char
*name, const char *title);
/**
Updates the Value on a Stored Variable
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param name unique identifier of the Stored Variable.
\param value the Variable Value in its textual representation.
\return 0 on failure: any other different value on success.
\sa gaia_stored_proc_create_tables, gaia_stored_proc_store,
gaia_stored_proc_fetch, gaia_stored_proc_delete,
gaia_stored_proc_update_title, gaia_stored_proc_update_sql,
gaia_stored_var_store, gaia_stored_var_store, gaia_stored_var_fetch,
gaia_stored_var_delete, gaia_stored_var_update_title
*/
SQLPROC_DECLARE int gaia_stored_var_update_value (sqlite3 *
handle,
const void
*cache,
const char
*name, const char *value);
/**
Executing a cooked SQL Procedure
\param handle pointer to the current DB connection.
\param cache the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\param sql the cooked SQL Body to be executed.
\return 0 on failure: any other different value on success.
\sa gaia_sql_proc_logfile
*/
SQLPROC_DECLARE int gaia_sql_proc_execute (sqlite3 *
handle,
const void *cache,
const char *sql);
#ifdef __cplusplus
}
#endif
#endif /* _SQLPROC_H */
libspatialite-5.1.0/src/headers/spatialite/geojson.h 0000644 0001750 0001750 00000036377 14463127014 017464 0000000 0000000 /*
geojson.h -- Gaia common support for the GeoJSON parser
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2018-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file geojson.h
GeoJSON structures
*/
#ifndef _GEOJSON_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GEOJSON_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* constant values for GeoJSON objects */
/** UNKNOWN */
#define GEOJSON_UNKNOWN 0
/** FeatureCollection object */
#define GEOJSON_FCOLLECTION 101
/** Feature object */
#define GEOJSON_FEATURE 102
/** Properties object */
#define GEOJSON_PROPERTIES 103
/* constant values for GeoJSON geometries */
/** POINT */
#define GEOJSON_POINT 201
/** LINESTRING */
#define GEOJSON_LINESTRING 202
/** POLYGON */
#define GEOJSON_POLYGON 203
/** MULTIPOINT */
#define GEOJSON_MULTIPOINT 204
/** MULTILINESTRING */
#define GEOJSON_MULTILINESTRING 205
/** MULTIPOLYGON */
#define GEOJSON_MULTIPOLYGON 206
/** GEOMETRYCOLLECTION */
#define GEOJSON_GEOMCOLLECTION 207
/* constant values for GeoJSON datatypes */
/** Text */
#define GEOJSON_TEXT 301
/** Integer (namely Int64) */
#define GEOJSON_INTEGER 302
/** Floating Point Double precision */
#define GEOJSON_DOUBLE 303
/** Boolean - TRUE */
#define GEOJSON_TRUE 304
/** Boolean - FALSE */
#define GEOJSON_FALSE 305
/** NULL */
#define GEOJSON_NULL 306
/* constant values for GeoJSON sizes */
/** number of objects per each block */
#define GEOJSON_BLOCK 4096
/** max fixed length for Text Strings */
#define GEOJSON_MAX 1024
/** number of stack levels */
#define GEOJSON_STACK 16
/* GeoJSON objects and data structures */
/**
an object wrapping a GeoJSON Property (aka data attribute)
*/
typedef struct geojson_property_str
{
/** Property name */
char *name;
/** datatype */
int type;
/** pointer to Text value */
char *txt_value;
/** Integer value */
sqlite3_int64 int_value;
/** Double value */
double dbl_value;
/** pointer to next item [linked list] */
struct geojson_property_str *next;
} geojson_property;
/**
pointer to Property
*/
typedef geojson_property *geojson_property_ptr;
/**
an object wrapping a GeoJSON Feature
*/
typedef struct geojson_feature_str
{
/** unique Feature ID */
int fid;
/** start offset; Geometry object */
long geom_offset_start;
/** end offset: Geometry object */
long geom_offset_end;
/** start offset: Properties object */
long prop_offset_start;
/** end offset: Properties object */
long prop_offset_end;
/** pointer to the Geometry string */
char *geometry;
/** linked list of Properties - pointer to first item */
geojson_property_ptr first;
/** linked list of Properties - pointer to last item */
geojson_property_ptr last;
} geojson_feature;
/**
pointer to Feature
*/
typedef geojson_feature *geojson_feature_ptr;
/**
an object wrapping an entry (aka Object) in the GeoJSON file
*/
typedef struct geojson_entry_str
{
/** name of the parent object [key] */
char *parent_key;
/** object type */
int type;
/** count of Properties children */
int properties;
/** count of Geometry children */
int geometry;
/** object's start offset */
long offset_start;
/** object's end offset */
long offset_end;
} geojson_entry;
/**
pointer to Entry
*/
typedef geojson_entry *geojson_entry_ptr;
/**
an object wrapping a block of entries in the GeoJSON file */
typedef struct geojson_block_str
{
/** index of the next free entry in the block */
int next_free_entry;
/** array of entries */
geojson_entry entries[GEOJSON_BLOCK];
/** pointer to next item [linked list] */
struct geojson_block_str *next;
} geojson_block;
/**
pointer to Block
*/
typedef geojson_block *geojson_block_ptr;
/**
an object wrapping a data Column
*/
typedef struct geojson_column_str
{
/** column name */
char *name;
/** number of Text values */
int n_text;
/** number of Int values */
int n_int;
/** number of Double values */
int n_double;
/** number of Boolean values */
int n_bool;
/** number of NULL values */
int n_null;
/** pointer to next item [linked list] */
struct geojson_column_str *next;
} geojson_column;
/**
pointer to Column
*/
typedef geojson_column *geojson_column_ptr;
/**
an object wrapping a GeoJSON parser
*/
typedef struct geojson_parser_str
{
/** file handle */
FILE *in;
/** linked list of Blocks - pointer to first item */
geojson_block_ptr first;
/** linked list of Blocks - pointer to last item */
geojson_block_ptr last;
/** total number of Features */
int count;
/** array of Features */
geojson_feature_ptr features;
/** linked list of Columns - pointer to first item */
geojson_column_ptr first_col;
/** linked list of Columns - pointer to last item */
geojson_column_ptr last_col;
/** total number of Point Geometries */
int n_points;
/** total number of Linestring Geometries */
int n_linestrings;
/** total number of Polygon Geometries */
int n_polygons;
/** total number of MultiPoint Geometries */
int n_mpoints;
/** total number of MultiLinestring Geometries */
int n_mlinestrings;
/** total number of MultiPolygon Geometries */
int n_mpolygons;
/** total number of GeometryCollection Geometries */
int n_geomcolls;
/** total number of NULL Geometries */
int n_geom_null;
/** total number of 2D Geometries */
int n_geom_2d;
/** total number of 3D Geometries */
int n_geom_3d;
/** total number of 4D Geometries */
int n_geom_4d;
/** Geometry Type cast function */
char cast_type[64];
/** Geometry Dims cast function */
char cast_dims[64];
} geojson_parser;
/**
pointer to Parser
*/
typedef geojson_parser *geojson_parser_ptr;
/**
an object wrapping a Key-Value pair
*/
typedef struct geojson_keyval_str
{
/** pointer to the Key string */
char *key;
/** pointer to the Value string */
char *value;
/** FALSE for quoted Text strings */
int numvalue;
/** pointer to next item [linked list] */
struct geojson_keyval_str *next;
} geojson_keyval;
/**
pointer to KeyValue
*/
typedef geojson_keyval *geojson_keyval_ptr;
/**
an object wrapping a stack entry
*/
typedef struct geojson_stack_entry_str
{
/** pointer to an Entry object */
geojson_entry_ptr obj;
/** linked list of KeyValues - pointer to first item */
geojson_keyval_ptr first;
/** linked list of KeyValues - pointer to last item */
geojson_keyval_ptr last;
} geojson_stack_entry;
/**
pointer to Stakc Entry
*/
typedef geojson_stack_entry *geojson_stack_entry_ptr;
/**
an object wrapping a GeoJSON stack
*/
typedef struct geojson_stack
{
/* a stack for parsing nested GeoJSON objects */
/** current stack level */
int level;
/** the stack levels array */
geojson_stack_entry entries[GEOJSON_STACK];
/** the Key parsing buffer */
char key[GEOJSON_MAX];
/** current Key index - last inserted byte */
int key_idx;
/** the Value parsing buffer - quote delimited strings */
char value[GEOJSON_MAX];
/** current Value index - last inserted byte */
int value_idx;
/** the Values parsing buffer - numeric values */
char numvalue[GEOJSON_MAX];
/** current numeric Value index - last inserted byte */
int numvalue_idx;
} geojson_stack;
/**
pointer to Stack
*/
typedef geojson_stack *geojson_stack_ptr;
/* function prototypes */
/**
Creates a new GeoJSON parser object
\param in an open FILE supposed to contain the GeoJSON text to be parsed
\return the pointer to newly created object
\sa geojson_destroy_parser, geojson_parser_init
\note you are responsible to destroy (before or after) any allocated
GeoJSON parser object.
*/
SPATIALITE_DECLARE geojson_parser_ptr geojson_create_parser (FILE * in);
/**
Destroys a GeoJSON parser object
\param p pointer to object to be destroyed
\sa geojson_create_parser
*/
SPATIALITE_DECLARE void geojson_destroy_parser (geojson_parser_ptr p);
/**
Fully initializes a GeoJSON parser object
\param parser pointer to a GeoJSON parser object
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\return 1 on success. 0 on failure (invalid GeoJSON text).
\sa geojson_create_parser, geojson_check_features
\note you are expected to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int geojson_parser_init (geojson_parser_ptr parser,
char **error_message);
/**
Checks a fully initialized GeoJSON parser object for containing valid Features
\param parser pointer to a GeoJSON parser object
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\return 1 on success. 0 on failure (invalid GeoJSON text).
\sa geojson_parser_init, geojson_create_features_index
\note you are expected to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int geojson_check_features (geojson_parser_ptr parser,
char **error_message);
/**
Creates the Features Index on a GeoJSON parser object
\param parser pointer to a GeoJSON parser object
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\return 1 on success. 0 on failure (invalid GeoJSON text).
\sa geojson_check_features
\note you are expected to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int geojson_create_features_index (geojson_parser_ptr
parser,
char **error_message);
/**
Will return the SQL CREATE TABLE statement
\param parser pointer to a GeoJSON parser object
\param table name of the SQL table to be created
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\return the SQL CREATE TABLE statement as a text string; NULL on failure
\sa geojson_check_features, geojson_sql_add_geometry, geojson_sql_create_rtree
geojson_insert_into
\note you are expected to free the SQL string returned by this
function by calling sqlite3_free() when it's no longer useful.
*/
SPATIALITE_DECLARE char *geojson_sql_create_table (geojson_parser_ptr
parser,
const char *table,
int colname_case);
/**
Will return the SQL AddGeometryColumn() statement
\param parser pointer to a GeoJSON parser object
\param table name of the SQL table being created
\param geom_col name of the Geometry column
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param srid the corresponding SRID value
\return the AddGeometryColumn() SQL string; NULL on failure
\sa geojson_check_features, geojson_sql_create_table, geojson_sql_create_rtree
geojson_insert_into
\note you are expected to free the SQL string returned by this
function by calling sqlite3_free() when it's no longer useful.
*/
SPATIALITE_DECLARE char *geojson_sql_add_geometry (geojson_parser_ptr
parser,
const char *table,
const char *geom_col,
int colname_case,
int srid);
/**
Will return the SQL CreateSpatialIndex() statement
\param table name of the SQL table being created
\param geom_col name of the Geometry column
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\return the CreateSpatialIndex() SQL string; NULL on failure
\sa geojson_check_features, geojson_sql_create_table, geojson_sql_add_geometry,
geojson_insert_into
\note you are expected to free the SQL string returned by this
function by calling sqlite3_free() when it's no longer useful.
*/
SPATIALITE_DECLARE char *geojson_sql_create_rtree (const char *table,
const char *geom_col,
int colname_case);
/**
Will return the SQL INSERT INTO statement
\param parser pointer to a GeoJSON parser object
\param table name of the SQL table being created
\param geom_col name of the Geometry column
\return the INSERT INTO SQL string; NULL on failure
\sa geojson_check_features, geojson_sql_create_table, geojson_add_geometry,
geojson_sql_create_rtree
\note you are expected to free the SQL string returned by this
function by calling sqlite3_free() when it's no longer useful.
*/
SPATIALITE_DECLARE char *geojson_sql_insert_into (geojson_parser_ptr
parser,
const char *table);
/**
Will fully initialize a Feature with all Property and Geometry values
\param parser pointer to a GeoJSON parser object
\param ft pointer the some GeoJson Feature object into the Parser
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\return 1 on success. 0 on failure (invalid GeoJSON Feature).
\sa geojson_create_features_index, geojson_reset_feature,
geojson_get_property_by_name
\note you are expected to free all Values returned by this function by
calling geojson_reset_feature() when they are no longer useful.
And you are expected also to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int geojson_init_feature (geojson_parser_ptr parser,
geojson_feature_ptr ft,
char **error_message);
/**
Will reset a Feature by freeing all Property and Geometry Values
\param ft pointer the some GeoJson Feature object into the Parser
\sa geojson_create_features_index, geojson_init_feature,
geojson_get_property_by_name
*/
SPATIALITE_DECLARE void geojson_reset_feature (geojson_feature_ptr ft);
/**
Will return the pointer to a given Property within a Feature
\param ft pointer the some GeoJson Feature object
\param name the name of some specific Property
\sa geojson_create_features_index, geojson_init_feature,
geojson_reset_feature
*/
SPATIALITE_DECLARE geojson_property_ptr
geojson_get_property_by_name (geojson_feature_ptr ft, const char *name);
#ifdef __cplusplus
}
#endif
#endif /* _GEOJSON_H */
libspatialite-5.1.0/src/headers/Makefile.am 0000644 0001750 0001750 00000001604 14463127014 015525 0000000 0000000
if MODULE_ONLY
noinst_HEADERS =
nobase_include_HEADERS =
else
noinst_HEADERS = spatialite_private.h
nobase_include_HEADERS = spatialite.h \
spatialite/gaiaconfig.h \
spatialite/gaiaconfig.h.in \
spatialite/gaiaconfig-msvc.h \
spatialite/gaiaconfig-msvc.h.in \
spatialite/gaiaexif.h \
spatialite/gaiaaux.h \
spatialite/gaiamatrix.h \
spatialite/gaiageo.h \
spatialite/gg_const.h \
spatialite/gg_structs.h \
spatialite/gg_core.h \
spatialite/gg_mbr.h \
spatialite/gg_formats.h \
spatialite/gg_dynamic.h \
spatialite/gg_advanced.h \
spatialite/gg_xml.h \
spatialite/gg_wfs.h \
spatialite/gg_dxf.h \
spatialite/spatialite_ext.h \
spatialite/sqlite.h \
spatialite/debug.h \
spatialite/geopackage.h \
spatialite/control_points.h \
spatialite/gaia_topology.h \
spatialite/gaia_network.h \
spatialite/gg_sequence.h \
spatialite/stored_procedures.h \
spatialite/geojson.h
endif
libspatialite-5.1.0/src/headers/spatialite.h 0000644 0001750 0001750 00000237144 14463127014 016013 0000000 0000000 /*
spatialite.h -- Gaia spatial support for SQLite
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/**
\file spatialite.h
Main SpatiaLite header file
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef _WIN32
#ifdef DLL_EXPORT
#define SPATIALITE_DECLARE __declspec(dllexport)
#else
#define SPATIALITE_DECLARE extern
#endif
#else
#define SPATIALITE_DECLARE __attribute__ ((visibility("default")))
#endif
#endif
#ifndef _SPATIALITE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _SPATIALITE_H
#endif
#define SPLITE_AXIS_1 0x51
#define SPLITE_AXIS_2 0x52
#define SPLITE_AXIS_NAME 0x3e
#define SPLITE_AXIS_ORIENTATION 0x3f
#ifdef __cplusplus
extern "C"
{
#endif
#include
#ifdef LOADABLE_EXTENSION
SPATIALITE_DECLARE int
sqlite3_spatialite_init (sqlite3 * db, char **pzErrMsg,
const sqlite3_api_routines * pApi);
#endif
/**
Initializes the library
\note you are always expected to explicitly call this function
before attempting to call any SpatiaLite own function.
*/
SPATIALITE_DECLARE void spatialite_initialize (void);
/**
Finalizes the library
\note you are always expected to explicitly call this function
immediately before exiting the main application.\n
This function will free any memory allocation and will release
any system resource internally used by the library.\n
*/
SPATIALITE_DECLARE void spatialite_shutdown (void);
/**
Return the current library version.
\return the version string.
*/
SPATIALITE_DECLARE const char *spatialite_version (void);
/**
Return the target CPU name.
\return the target CPU string.
*/
SPATIALITE_DECLARE const char *spatialite_target_cpu (void);
/**
Initializes the internal memory block supporting each connection
\sa spatialite_init_ex, spatialite_cleanup_ex
*/
SPATIALITE_DECLARE void *spatialite_alloc_connection (void);
/**
Disables reporting GEOS/RTTOPO error and warnings on stderr
\param ptr a memory pointer returned by spatialite_alloc_connection()
\sa spatialite_init_ex, spatialite_cleanup_ex,
spatialite_set_verbose_mode
*/
SPATIALITE_DECLARE void spatialite_set_silent_mode (const void *ptr);
/**
Enables reporting GEOS/RTTOPO error and warnings on stderr
\param ptr a memory pointer returned by spatialite_alloc_connection()
\sa spatialite_init_ex, spatialite_cleanup_ex,
spatialite_set_silent_mode
*/
SPATIALITE_DECLARE void spatialite_set_verbode_mode (const void *ptr);
/**
Initializes a SpatiaLite connection.
This function is now \b DEPRECATED because is not reentrant (not thread safe);
use spatialite_init_ex() for all new development.
\param verbose if TRUE a short start-up message is shown on stderr
\sa spatialite_cleanup, spatialite_init_ex
\note You absolutely must invoke this function before attempting to perform
any other SpatiaLite's call.
*/
SPATIALITE_DECLARE void spatialite_init (int verbose);
/**
Initializes a SpatiaLite connection.
\param db_handle handle to the current SQLite connection
\param ptr a memory pointer returned by spatialite_alloc_connection()
\param verbose if TRUE a short start-up message is shown on stderr
\sa spatialite_alloc_connection, spatialite_cleanup_ex, spatialite_init
\note You absolutely must invoke this function before attempting to perform
any other SpatiaLite's call.
*/
SPATIALITE_DECLARE void spatialite_init_ex (sqlite3 * db_handle,
const void *ptr, int verbose);
/**
Initializes the GEOS library.
\note You are never supposed to invoke this function (internally handled).
*/
SPATIALITE_DECLARE void spatialite_init_geos (void);
/**
Cleanup a SpatiaLite connection
This function is now \b DEPRECATED; use spatialite_cleanup_ex() for all new development.
This function performs general cleanup, essentially undoing the effect
of spatialite_init().
\sa spatialite_init
*/
SPATIALITE_DECLARE void spatialite_cleanup (void);
/**
Cleanup a SpatiaLite connection
This function performs general cleanup, essentially undoing the effect
of spatialite_init_ex().
\param ptr the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\sa spatialite_init_ex, spatialite_alloc_connection
*/
SPATIALITE_DECLARE void spatialite_cleanup_ex (const void *ptr);
/**
Partially Cleaning-up a SpatiaLite connection
This function will destroy all TopoGeo and TopoNet objects from within a local cache.
\param ptr the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\sa spatialite_init_ex, spatialite_alloc_connection
*/
SPATIALITE_DECLARE void spatialite_finalize_topologies (const void *ptr);
/**
Enables the BLOB-TinyPoint encoding
\param ptr the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\sa disable_tiny_point, is_tiny_point_enabled
*/
SPATIALITE_DECLARE void enable_tiny_point (const void *ptr);
/**
Disables the BLOB-TinyPoint encoding
\param ptr the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\sa disable_tiny_point, is_tiny_point_enabled
*/
SPATIALITE_DECLARE void disable_tiny_point (const void *ptr);
/**
Checks if the BLOB-TinyPoint encoding is enabled or not
\param ptr the same memory pointer passed to the corresponding call to
spatialite_init_ex() and returned by spatialite_alloc_connection()
\return 0 (FALSE) if not enabled, any other value (TRUE) if enabled
\sa enable_tiny_point, disable_tiny_point
*/
SPATIALITE_DECLARE int is_tiny_point_enabled (const void *ptr);
/**
Dumps a full geometry-table into an external Shapefile
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param column the name of the geometry column
\param shp_path pathname of the Shapefile to be exported (no suffix)
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param geom_type "POINT", "LINESTRING", "POLYGON", "MULTIPOINT" or NULL
\param verbose if TRUE a short report is shown on stderr
\param rows on completion will contain the total number of exported rows
\param err_msg on completion will contain an error message (if any)
\sa dump_shapefile_ex
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_shapefile (sqlite3 * sqlite, char *table,
char *column, char *shp_path,
char *charset, char *geom_type,
int verbose, int *rows,
char *err_msg);
/**
Dumps a full geometry-table into an external Shapefile
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param column the name of the geometry column
\param shp_path pathname of the Shapefile to be exported (no suffix)
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param geom_type "POINT", "LINESTRING", "POLYGON", "MULTIPOINT" or NULL
\param verbose if TRUE a short report is shown on stderr
\param rows on completion will contain the total number of exported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\sa dump_shapefile
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_shapefile_ex (sqlite3 * sqlite, char *table,
char *column, char *shp_path,
char *charset, char *geom_type,
int verbose, int *rows,
int colcase_name, char *err_msg);
/**
Dumps a full geometry-table into an external Shapefile
\param sqlite handle to current DB connection
\param proj_ctx pointer to the current PROJ.6 context (may be NULL)
\param table the name of the table to be exported
\param column the name of the geometry column
\param shp_path pathname of the Shapefile to be exported (no suffix)
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param geom_type "POINT", "LINESTRING", "POLYGON", "MULTIPOINT" or NULL
\param verbose if TRUE a short report is shown on stderr
\param rows on completion will contain the total number of exported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\sa dump_shapefile
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_shapefile_ex2 (sqlite3 * sqlite, void *proj_ctx,
char *table, char *column,
char *shp_path, char *charset,
char *geom_type, int verbose,
int *rows, int colcase_name,
char *err_msg);
/**
Loads an external Shapefile into a newly created table
\param sqlite handle to current DB connection
\param shp_path pathname of the Shapefile to be imported (no suffix)
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param srid the SRID to be set for Geometries
\param column the name of the geometry column
\param coerce2d if TRUE any Geometry will be casted to 2D [XY]
\param compressed if TRUE compressed Geometries will be created
\param verbose if TRUE a short report is shown on stderr
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param rows on completion will contain the total number of imported rows
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
\sa load_shapefile_ex, load_shapefile_ex2, load_shapefile_ex3
\note this function simply calls load_shapefile_ex by passing
implicit gype="AUTO" and pk_column=NULL arguments
*/
SPATIALITE_DECLARE int load_shapefile (sqlite3 * sqlite, char *shp_path,
char *table, char *charset, int srid,
char *column, int coerce2d,
int compressed, int verbose,
int spatial_index, int *rows,
char *err_msg);
/**
Loads an external Shapefile into a newly created table
\param sqlite handle to current DB connection
\param shp_path pathname of the Shapefile to be imported (no suffix)
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param srid the SRID to be set for Geometries
\param geo_column the name of the geometry column
\param gtype expected to be one of: "LINESTRING", "LINESTRINGZ",
"LINESTRINGM", "LINESTRINGZM", "MULTILINESTRING", "MULTILINESTRINGZ",
"MULTILINESTRINGM", "MULTILINESTRINGZM", "POLYGON", "POLYGONZ", "POLYGONM",
"POLYGONZM", "MULTIPOLYGON", "MULTIPOLYGONZ", "MULTIPOLYGONM",
"MULTIPOLYGONZM" or "AUTO".
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param coerce2d if TRUE any Geometry will be casted to 2D [XY]
\param compressed if TRUE compressed Geometries will be created
\param verbose if TRUE a short report is shown on stderr
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param rows on completion will contain the total number of imported rows
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
\sa load_shapefile, load_shapefile_ex2, load_shapefile_ex3
\note the Shapefile format doesn't supports any distinction between
LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
as does not allows to clearly distinguish if the M-measure is required.
\n So a first preliminary scan of the Shapefile is required in order to
correctly identify the actual payload (gtype = "AUTO", default case).
\n By explicitly specifying some expected geometry type this first scan
will be skipped at all thus introducing a noticeable performance gain.
\n Anyway, declaring a mismatching geometry type will surely cause a failure.
*/
SPATIALITE_DECLARE int load_shapefile_ex (sqlite3 * sqlite, char *shp_path,
char *table, char *charset,
int srid, char *geo_column,
char *gtype, char *pk_column,
int coerce2d, int compressed,
int verbose, int spatial_index,
int *rows, char *err_msg);
/**
Loads an external Shapefile into a newly created table
\param sqlite handle to current DB connection
\param shp_path pathname of the Shapefile to be imported (no suffix)
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param srid the SRID to be set for Geometries
\param geo_column the name of the geometry column
\param gtype expected to be one of: "LINESTRING", "LINESTRINGZ",
"LINESTRINGM", "LINESTRINGZM", "MULTILINESTRING", "MULTILINESTRINGZ",
"MULTILINESTRINGM", "MULTILINESTRINGZM", "POLYGON", "POLYGONZ", "POLYGONM",
"POLYGONZM", "MULTIPOLYGON", "MULTIPOLYGONZ", "MULTIPOLYGONM",
"MULTIPOLYGONZM" or "AUTO".
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param coerce2d if TRUE any Geometry will be casted to 2D [XY]
\param compressed if TRUE compressed Geometries will be created
\param verbose if TRUE a short report is shown on stderr
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
\sa load_shapefile, load_shapefile_ex, load_shapefile_ex3
\note the Shapefile format doesn't supports any distinction between
LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
as does not allows to clearly distinguish if the M-measure is required.
\n So a first preliminary scan of the Shapefile is required in order to
correctly identify the actual payload (gtype = "AUTO", default case).
\n By explicitly specifying some expected geometry type this first scan
will be skipped at all thus introducing a noticeable performance gain.
\n Anyway, declaring a mismatching geometry type will surely cause a failure.
*/
SPATIALITE_DECLARE int load_shapefile_ex2 (sqlite3 * sqlite, char *shp_path,
char *table, char *charset,
int srid, char *geo_column,
char *gtype, char *pk_column,
int coerce2d, int compressed,
int verbose, int spatial_index,
int text_date, int *rows,
char *err_msg);
/**
Loads an external Shapefile into a newly created table
\param sqlite handle to current DB connection
\param shp_path pathname of the Shapefile to be imported (no suffix)
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param srid the SRID to be set for Geometries
\param geo_column the name of the geometry column
\param gtype expected to be one of: "LINESTRING", "LINESTRINGZ",
"LINESTRINGM", "LINESTRINGZM", "MULTILINESTRING", "MULTILINESTRINGZ",
"MULTILINESTRINGM", "MULTILINESTRINGZM", "POLYGON", "POLYGONZ", "POLYGONM",
"POLYGONZM", "MULTIPOLYGON", "MULTIPOLYGONZ", "MULTIPOLYGONM",
"MULTIPOLYGONZM" or "AUTO".
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param coerce2d if TRUE any Geometry will be casted to 2D [XY]
\param compressed if TRUE compressed Geometries will be created
\param verbose if TRUE a short report is shown on stderr
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
\sa load_shapefile, load_shapefile_ex, load_shapefile_ex2, load_zip_shapefile
\note the Shapefile format doesn't supports any distinction between
LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
as does not allows to clearly distinguish if the M-measure is required.
\n So a first preliminary scan of the Shapefile is required in order to
correctly identify the actual payload (gtype = "AUTO", default case).
\n By explicitly specifying some expected geometry type this first scan
will be skipped at all thus introducing a noticeable performance gain.
\n Anyway, declaring a mismatching geometry type will surely cause a failure.
*/
SPATIALITE_DECLARE int load_shapefile_ex3 (sqlite3 * sqlite,
const char *shp_path,
const char *table,
const char *charset, int srid,
const char *geo_column,
const char *gtype,
const char *pk_column,
int coerce2d, int compressed,
int verbose, int spatial_index,
int text_date, int *rows,
int colname_case, char *err_msg);
/**
Loads an external Shapefile (from Zipfile) into a newly created table
\param sqlite handle to current DB connection
\param zip_path pathname of the Zipfile
\param shp_path pseudo-pathname of the Shapefile to be imported (no suffix)
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param srid the SRID to be set for Geometries
\param geo_column the name of the geometry column
\param gtype expected to be one of: "LINESTRING", "LINESTRINGZ",
"LINESTRINGM", "LINESTRINGZM", "MULTILINESTRING", "MULTILINESTRINGZ",
"MULTILINESTRINGM", "MULTILINESTRINGZM", "POLYGON", "POLYGONZ", "POLYGONM",
"POLYGONZM", "MULTIPOLYGON", "MULTIPOLYGONZ", "MULTIPOLYGONM",
"MULTIPOLYGONZM" or "AUTO".
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param coerce2d if TRUE any Geometry will be casted to 2D [XY]
\param compressed if TRUE compressed Geometries will be created
\param verbose if TRUE a short report is shown on stderr
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
\sa load_shapefile_ex3
\note the Shapefile format doesn't supports any distinction between
LINESTRINGs and MULTILINESTRINGs, or between POLYGONs and MULTIPOLYGONs;
as does not allows to clearly distinguish if the M-measure is required.
\n So a first preliminary scan of the Shapefile is required in order to
correctly identify the actual payload (gtype = "AUTO", default case).
\n By explicitly specifying some expected geometry type this first scan
will be skipped at all thus introducing a noticeable performance gain.
\n Anyway, declaring a mismatching geometry type will surely cause a failure.
*/
SPATIALITE_DECLARE int load_zip_shapefile (sqlite3 * sqlite,
const char *zip_path,
const char *shp_path,
const char *table,
const char *charset, int srid,
const char *geo_column,
const char *gtype,
const char *pk_column,
int coerce2d, int compressed,
int verbose, int spatial_index,
int text_date, int *rows,
int colname_case, char *err_msg);
/**
Loads an external DBF file into a newly created table
\param sqlite handle to current DB connection
\param dbf_path pathname of the DBF file to be imported
\param table the name of the table to be created
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param verbose if TRUE a short report is shown on stderr
\param rows on completion will contain the total number of actually exported rows
\param err_msg on completion will contain an error message (if any)
\sa load_dbf_ex, load_dbf_ex2, load_dbf_ex3
\note this function simply calls load_dbf_ex by passing an
implicit pk_column=NULL argument
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_dbf (sqlite3 * sqlite, char *dbf_path,
char *table, char *charset, int verbose,
int *rows, char *err_msg);
/**
Loads an external DBF file into a newly created table
\param sqlite handle to current DB connection
\param dbf_path pathname of the DBF file to be imported
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param verbose if TRUE a short report is shown on stderr
\param rows on completion will contain the total number of actually exported rows
\param err_msg on completion will contain an error message (if any)
\sa load_dbf, load_dbf_ex2, load_dbf_ex3
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_dbf_ex (sqlite3 * sqlite, char *dbf_path,
char *table, char *pk_column,
char *charset, int verbose, int *rows,
char *err_msg);
/**
Loads an external DBF file into a newly created table
\param sqlite handle to current DB connection
\param dbf_path pathname of the DBF file to be imported
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param verbose if TRUE a short report is shown on stderr
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param err_msg on completion will contain an error message (if any)
\sa load_dbf, load_dbf_ex, load_dbf_ex3
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_dbf_ex2 (sqlite3 * sqlite, char *dbf_path,
char *table, char *pk_column,
char *charset, int verbose,
int text_date, int *rows,
char *err_msg);
/**
Loads an external DBF file into a newly created table
\param sqlite handle to current DB connection
\param dbf_path pathname of the DBF file to be imported
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param verbose if TRUE a short report is shown on stderr
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\sa load_dbf, load_dbf_ex, load_dbf_ex2, load_zip_dbf
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_dbf_ex3 (sqlite3 * sqlite, const char *dbf_path,
const char *table,
const char *pk_column,
const char *charset, int verbose,
int text_date, int *rows,
int colname_case, char *err_msg);
/**
Loads an external DBF file (from Zipfile) into a newly created table
\param sqlite handle to current DB connection
\param zip_path pathname of the Zipfile
\param shp_path pseudo-pathname of the Shapefile to be imported (no suffix)
\param sqlite handle to current DB connection
\param zip_path pathname of the Zipfile
\param filenamepseudo-pathname of the DBF file to be imported (including the '.dbf' suffix)
\param table the name of the table to be created
\param pk_column name of the Primary Key column; if NULL or mismatching
then "PK_UID" will be assumed by default.
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param verbose if TRUE a short report is shown on stderr
\param text_dates is TRUE all DBF dates will be considered as TEXT
\param rows on completion will contain the total number of imported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\sa load_dbf_ex3
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_zip_dbf (sqlite3 * sqlite, const char *zip_file,
const char *dbf_path,
const char *table,
const char *pk_column,
const char *charset, int verbose,
int text_date, int *rows,
int colname_case, char *err_msg);
/**
Dumps a full table into an external DBF file
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param dbf_path pathname of the DBF to be exported
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param err_msg on completion will contain an error message (if any)
\sa dump_dbf_ex, dump_dbf_ex2
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_dbf (sqlite3 * sqlite, char *table,
char *dbf_path, char *charset,
char *err_msg);
/**
Dumps a full table into an external DBF file
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param dbf_path pathname of the DBF to be exported
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param rows on completion will contain the total number of exported rows
\param err_msg on completion will contain an error message (if any)
\sa dump_dbf, dump_dbf_ex2
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_dbf_ex (sqlite3 * sqlite, char *table,
char *dbf_path, char *charset,
int *rows, char *err_msg);
/**
Dumps a full table into an external DBF file
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param dbf_path pathname of the DBF to be exported
\param charset a valid GNU ICONV charset to be used for DBF text strings
\param rows on completion will contain the total number of exported rows
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param err_msg on completion will contain an error message (if any)
\sa dump_dbf, dump_dbf_ex
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_dbf_ex2 (sqlite3 * sqlite, char *table,
char *dbf_path, char *charset,
int *rows, int colname_case,
char *err_msg);
/**
Loads an external spreadsheet (.xls) file into a newly created table
\param sqlite handle to current DB connection
\param path pathname of the spreadsheet file to be imported
\param table the name of the table to be created
\param worksheetIndex the index identifying the worksheet to be imported
\param first_titles if TRUE the first line is assumed to contain column names
\param rows on completion will contain the total number of actually exported rows
\param err_msg on completion will contain an error message (if any)
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int load_XL (sqlite3 * sqlite, const char *path,
const char *table,
unsigned int worksheetIndex,
int first_titles, unsigned int *rows,
char *err_msg);
/**
A portable replacement for C99 round()
\param value a double value
\return the nearest integeral value
*/
SPATIALITE_DECLARE double math_round (double value);
/**
A portable replacement for C99 llabs()
\param value a 64 bit integer value
\return the corresponding absolute value
*/
SPATIALITE_DECLARE sqlite3_int64 math_llabs (sqlite3_int64 value);
/**
Inserts the inlined EPSG dataset into the "spatial_ref_sys" table
\param sqlite handle to current DB connection
\param verbose if TRUE a short report is shown on stderr
\return 0 on failure, any other value on success
\sa spatial_ref_sys_init2
\note this function is internally invoked by the SQL function
InitSpatialMetadata(), and is not usually intended for direct use.
This functions is now deprecated, and will simply call
spatial_ref_sys_init2(sqlite, GAIA_EPSG_ANY, verbose).
*/
SPATIALITE_DECLARE int spatial_ref_sys_init (sqlite3 * sqlite, int verbose);
/**
Inserts the inlined EPSG dataset into the "spatial_ref_sys" table
\param sqlite handle to current DB connection
\param mode can be one of GAIA_EPSG_ANY, GAIA_EPSG_NONE or GAIA_EPSG_WGS84_ONLY
\param verbose if TRUE a short report is shown on stderr
\return 0 on failure, any other value on success
\note this function is internally invoked by the SQL function
InitSpatialMetadata(), and is not usually intended for direct use.
*/
SPATIALITE_DECLARE int spatial_ref_sys_init2 (sqlite3 * sqlite, int mode,
int verbose);
/**
Inserts some inlined EPSG definition into the "spatial_ref_sys" table
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int insert_epsg_srid (sqlite3 * sqlite, int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
determining if it is of the geographic type
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\param geographic on successful completion will contain TRUE or FALSE
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int srid_is_geographic (sqlite3 * sqlite, int srid,
int *geographic);
/**
checks a SRID definition from the "spatial_ref_sys" table
determining if it is of the projected type
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\param projected on successful completion will contain TRUE or FALSE
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int srid_is_projected (sqlite3 * sqlite, int srid,
int *projected);
/**
checks a SRID definition from the "spatial_ref_sys" table
determining if the axes order is X-Y or Y-X
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\param flipped on successful completion will contain 0 (FALSE) if axes order
is X-Y, any other value (TRUE) if axes order is Y-X.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int srid_has_flipped_axes (sqlite3 * sqlite, int srid,
int *flipped);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning the corresponding Spheroid name
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return the Spheroid name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_spheroid (sqlite3 * sqlite, int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning the corresponding Prime Meridian name
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return the Prime Meridian name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_prime_meridian (sqlite3 * sqlite,
int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning the corresponding Projection name
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return the Projection name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_projection (sqlite3 * sqlite, int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning the corresponding Datum name
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return the Datum name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_datum (sqlite3 * sqlite, int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning the corresponding Unit name
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\return the Unit name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_unit (sqlite3 * sqlite, int srid);
/**
checks a SRID definition from the "spatial_ref_sys" table
then returning an Axis definition
\param sqlite handle to current DB connection
\param srid the SRID value uniquely identifying the required EPSG definition
\param axis should be one of SPLITE_AXIS_1 or SPLITE_AXIS_2
\param mode should be one of SPLITE_AXIS_NAME or SPLITE_AXIS_ORIENTATION
\return the reqested name on succes, NULL on failure
\note you are responsible for freeing the returned name.
*/
SPATIALITE_DECLARE char *srid_get_axis (sqlite3 * sqlite, int srid,
char axis, char mode);
/**
Checks if a column is actually defined into the given table
\param sqlite handle to current DB connection
\param table the table to be checked
\param column the column to be checked
\return 0 on success, any other value on success
\note internally used to detect if some KML attribute defaults to a constant value
*/
SPATIALITE_DECLARE int
is_kml_constant (sqlite3 * sqlite, char *table, char *column);
/**
Dumps a full geometry-table into an external KML file
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param geom_col the name of the geometry column
\param kml_path pathname of the KML file to be exported
\param name_col column to be used for KML "name" (may be null)
\param desc_col column to be used for KML "description" (may be null)
\param precision number of decimal digits for coordinates
\sa dump_kml_ex
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_kml (sqlite3 * sqlite, char *table,
char *geom_col, char *kml_path,
char *name_col, char *desc_col,
int precision);
/**
Dumps a full geometry-table into an external KML file
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param geom_col the name of the geometry column
\param kml_path pathname of the KML file to be exported
\param name_col column to be used for KML "name" (may be null)
\param desc_col column to be used for KML "description" (may be null)
\param precision number of decimal digits for coordinates
\param rows on completion will contain the total number of exported rows
\sa dump_kml
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_kml_ex (sqlite3 * sqlite, char *table,
char *geom_col, char *kml_path,
char *name_col, char *desc_col,
int precision, int *rows);
/**
Checks for duplicated rows into the same table
\param sqlite handle to current DB connection
\param table name of the table to be checked
\param dupl_count on completion will contain the number of duplicated rows found
\sa remove_duplicated_rows
\note two (or more) rows are assumed to be duplicated if any column
value (excluding any Primary Key column) is exacly the same
*/
SPATIALITE_DECLARE void check_duplicated_rows (sqlite3 * sqlite,
char *table,
int *dupl_count);
/**
Remove duplicated rows from a table
\param sqlite handle to current DB connection
\param table name of the table to be cleaned
\sa check_duplicated_rows, remove_duplicated_rows_ex
\note when two (or more) duplicated rows exist, only the first occurrence
will be preserved, then deleting any further occurrence.
*/
SPATIALITE_DECLARE void remove_duplicated_rows (sqlite3 * sqlite,
char *table);
/**
Remove duplicated rows from a table
\param sqlite handle to current DB connection
\param table name of the table to be cleaned
\param removed on successful completion will contain the total
count of removed duplicate rows
\sa check_duplicated_rows, remove_duplicated_rows_ex2
\note when two (or more) duplicated rows exist, only the first occurrence
will be preserved, then deleting any further occurrence.
*/
SPATIALITE_DECLARE void remove_duplicated_rows_ex (sqlite3 * sqlite,
char *table,
int *removed);
/**
Remove duplicated rows from a table
\param sqlite handle to current DB connection
\param table name of the table to be cleaned
\param removed on successful completion will contain the total
count of removed duplicate rows
\param transaction boolena; if set to TRUE will internally handle
a SQL Transaction
\sa check_duplicated_rows, remove_duplicated_rows
\note when two (or more) duplicated rows exist, only the first occurrence
will be preserved, then deleting any further occurrence.
*/
SPATIALITE_DECLARE void remove_duplicated_rows_ex2 (sqlite3 * sqlite,
char *table,
int *removed,
int transaction);
/**
Creates a derived table surely containing elementary Geometries
\param sqlite handle to current DB connection
\param inTable name of the input table
\param geometry name of the Geometry column
\param outTable name of the output table to be created
\param pKey name of the Primary Key column in the output table
\param multiId name of the column identifying origins in the output table
\sa elementary_geometries_ex
\note if the input table contains some kind of complex Geometry
(MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
then many rows are inserted into the output table: each single
row will contain the same attributes and an elementaty Geometry.
All the rows created by expanding the same input row will expose
the same value in the "multiId" column.
*/
SPATIALITE_DECLARE void elementary_geometries (sqlite3 * sqlite,
char *inTable,
char *geometry,
char *outTable, char *pKey,
char *multiId);
/**
Creates a derived table surely containing elementary Geometries
\param sqlite handle to current DB connection
\param inTable name of the input table
\param geometry name of the Geometry column
\param outTable name of the output table to be created
\param pKey name of the Primary Key column in the output table
\param multiId name of the column identifying origins in the output table
\param rows on completion will contain the total number of inserted rows
\sa elementary_geometries_ex2
\note if the input table contains some kind of complex Geometry
(MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
then many rows are inserted into the output table: each single
row will contain the same attributes and an elementaty Geometry.
All the rows created by expanding the same input row will expose
the same value in the "multiId" column.
*/
SPATIALITE_DECLARE void elementary_geometries_ex (sqlite3 * sqlite,
char *inTable,
char *geometry,
char *outTable,
char *pKey, char *multiId,
int *rows);
/**
Creates a derived table surely containing elementary Geometries
\param sqlite handle to current DB connection
\param inTable name of the input table
\param geometry name of the Geometry column
\param outTable name of the output table to be created
\param pKey name of the Primary Key column in the output table
\param multiId name of the column identifying origins in the output table
\param rows on completion will contain the total number of inserted rows
\param transaction boolena; if set to TRUE will internally handle
a SQL Transaction
\sa elementary_geometries_ex3
\note if the input table contains some kind of complex Geometry
(MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
then many rows are inserted into the output table: each single
row will contain the same attributes and an elementaty Geometry.
All the rows created by expanding the same input row will expose
the same value in the "multiId" column.
*/
SPATIALITE_DECLARE void elementary_geometries_ex2 (sqlite3 * sqlite,
char *inTable,
char *geometry,
char *outTable,
char *pKey,
char *multiId, int *rows,
int transaction);
/**
Creates a derived table surely containing elementary Geometries
\param sqlite handle to current DB connection
\param inTable name of the input table
\param geometry name of the Geometry column
\param outTable name of the output table to be created
\param pKey name of the Primary Key column in the output table
\param multiId name of the column identifying origins in the output table
\param options pointer to an Options list created by gaiaAuxClonerCreate()
\param rows on completion will contain the total number of inserted rows
\param transaction boolena; if set to TRUE will internally handle
a SQL Transaction
\sa elementary_geometries
\note if the input table contains some kind of complex Geometry
(MULTIPOINT, MULTILINESTRING, MULTIPOLYGON or GEOMETRYCOLLECTION),
then many rows are inserted into the output table: each single
row will contain the same attributes and an elementaty Geometry.
All the rows created by expanding the same input row will expose
the same value in the "multiId" column.
*/
SPATIALITE_DECLARE void elementary_geometries_ex3 (sqlite3 * sqlite,
char *inTable,
char *geometry,
char *outTable,
char *pKey,
char *multiId,
const void *options,
int *rows,
int transaction);
/**
Dumps a full geometry-table into an external GeoJSON file (old specification)
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param geom_col the name of the geometry column
\param outfile_path pathname for the GeoJSON file to be written to
\param precision number of decimal digits for coordinates
\param option the format to use for output
\sa dump_geojson_ex, dump_geojson2
\note valid values for option are:
- 0 no option
- 1 GeoJSON MBR
- 2 GeoJSON Short CRS (e.g EPSG:4326)
- 3 MBR + Short CRS
- 4 GeoJSON Long CRS (e.g urn:ogc:def:crs:EPSG::4326)
- 5 MBR + Long CRS
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_geojson (sqlite3 * sqlite, char *table,
char *geom_col, char *outfile_path,
int precision, int option);
/**
Dumps a full geometry-table into an external GeoJSON file (old specification)
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param geom_col the name of the geometry column
\param outfile_path pathname for the GeoJSON file to be written to
\param precision number of decimal digits for coordinates
\param option the format to use for output
\param rows on completion will contain the total number of exported rows
\sa dump_geojson, dump_geojson2
\note valid values for option are:
- 0 no option
- 1 GeoJSON MBR
- 2 GeoJSON Short CRS (e.g EPSG:4326)
- 3 MBR + Short CRS
- 4 GeoJSON Long CRS (e.g urn:ogc:def:crs:EPSG::4326)
- 5 MBR + Long CRS
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int dump_geojson_ex (sqlite3 * sqlite, char *table,
char *geom_col, char *outfile_path,
int precision, int option,
int *rows);
/**
Dumps a full geometry-table into an external GeoJSON file (RFC 7946)
\param sqlite handle to current DB connection
\param table the name of the table to be exported
\param geom_col the name of the geometry column
\param outfile_path pathname for the GeoJSON file to be written to
\param precision number of decimal digits for coordinates
\param lon_lat TRUE if all coordinates are expressed as WGS84 longitudes
and latitudes (as required by RFC 7946); FALSE if they are in some
other (undefined) CRS
\param m_coords TRUE if M-values will be exported as ordinary coordinates;
FALSE for strict RFC 7946 conformance (no M-Values at all)
\param indent TRUE if the GeoJSON file will be properly indented for enhanced
human readibility; FALSE if the GeoJSON file will be in a single monolithic
line without blank spaces.
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param rows on completion will contain the total number of exported rows
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\sa dump_geojson, dump_geojson_ex
\return 0 on failure, any other value on success
\note you are expected to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int dump_geojson2 (sqlite3 * sqlite, char *table,
char *geom_col, char *outfile_path,
int precision, int lon_lat,
int m_coords, int indented,
int colname_case, int *rows,
char **error_message);
/**
Loads an external GeoJSON file into a newly created table
\param sqlite handle to current DB connection
\param path pathname of the GeoJSON file to be imported
\param table the name of the table to be created
\param column the name of the geometry column. If NULL the column
will be silently named "geometry".
\param spatial_index if TRUE an R*Tree Spatial Index will be created
\param srid when positive, the SRID value to be assigned to all Geometries.
If 0 or negative SRID=4326 (lon-lat WGS84) will be always assumed accordingly
to RFC 7946.
\param colname_case one between GAIA_DBF_COLNAME_LOWERCASE,
GAIA_DBF_COLNAME_UPPERCASE or GAIA_DBF_COLNAME_CASE_IGNORE.
\param rows on completion will contain the total number of imported rows
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\return 0 on failure, any other value on success
\note you are expected to free before or later an eventual error
message by calling sqlite3_free()
*/
SPATIALITE_DECLARE int load_geojson (sqlite3 * sqlite, char *path,
char *table, char *column,
int spatial_index, int srid,
int colname_case, int *rows,
char **error_message);
/**
Updates the LAYER_STATICS metadata table
\param sqlite handle to current DB connection
\param table name of the table to be processed
\param column name of the geometry to be processed
\note this function will explore the given table/geometry determining
the number of rows and the full layer extent; a corresponding table/geometry
entry is expected to be already declared in the GEOMETRY_COLUMNS table.
These informations will be permanently stored into the LAYER_STATISTICS
table; if such table does not yet exists will be implicitly created.
- if table is NULL, any entry found within GEOMETRY_COLUMNS
will be processed.
- if table is not NULL and column is NULL, any geometry
belonging to the given table will be processed.
- if both table and column are not NULL, then only the
given entry will be processed.
\sa gaiaStatisticsInvalidate, gaiaGetLayerExtent, gaiaGetVectorLayersList
\return 0 on failure, the total count of processed entries on success
*/
SPATIALITE_DECLARE int update_layer_statistics (sqlite3 * sqlite,
const char *table,
const char *column);
/**
Immediately and unconditionally invalidates the already existing Statistics
\param handle SQLite handle to current DB connection.
\param table VectorLayer Table (or View, or VirtualShape).
\param geometry Geometry Column name.
\return 0 on success, any other value on success
\sa update_layer_statistics, gaiaGetLayerExtent, gaiaGetVectorLayersList
\note if the table arg is NULL all Statistics for any VectorLayer defined within
the DB will be invalidated; otherwise only a single Layer will be affectedd (if existing).
\n By defining the geometry arg (not NULL) you can further restrict your selection.
*/
SPATIALITE_DECLARE int gaiaStatisticsInvalidate (sqlite3 * handle,
const char *table,
const char *geometry);
/**
Queries the Metadata tables returning the Layer Full Extent
\param handle SQLite handle to current DB connection.
\param table VectorLayer Table (or View, or VirtualShape).
\param geometry Geometry Column name.
\param mode if TRUE a PESSIMISTIC statistics update will be implied,
otherwise OPTIMISTIC.
\return the pointer to the newly created Geometry (Envelope): NULL on failure
\sa update_layer_statistic, gaiaStatisticsInvalidate, gaiaGetVectorLayersList
\note you are responsible to destroy (before or after) any allocated
Geometry returned by gaiaGetLayerExtent().
\n The geometry arg is optional when the table simply has a single Geometry Column,
and can be NULL in this case.
\n When the mode arg is set to FALSE (default) then the returned infos
will be simply retrieved from the staticized statistic tables (faster, but could be inaccurate).
\n If the mode arg is set to TRUE a preliminary attempt to update the
statistic tables will be always performed (probably slower, but surely accurate).
\n If the named Layer doesn't exist, or if it's completely empty (not containing
any valid Geometry) NULL will be returned.
*/
SPATIALITE_DECLARE gaiaGeomCollPtr gaiaGetLayerExtent (sqlite3 * handle,
const char *table,
const char *geometry,
int mode);
/**
Queries the Metadata tables supporting Vector Layers
\param handle SQLite handle to current DB connection.
\param table VectorLayer Table (or View, or VirtualShape).
\param geometry Geometry Column name.
\param mode one of GAIA_VECTORS_LIST_OPTIMISTIC or GAIA_VECTORS_LIST_PESSIMISTIC.
\return the pointer to the newly created VectorLayersList object: NULL on failure
\sa gaiaFreeVectorLayersList, update_layer_statistics, gaiaStatisticsInvalidate,
gaiaGetLayerExtent, gaiaGetVectorLayersList
\note you are responsible to destroy (before or after) any allocated
VectorLayersList returned by gaiaGetVectorLayersList().
\n If the table arg is NULL all VectorLayers defined within the DB will be reported
(and in this case all AttributeField Infos will be always suppressed);
otherwise only a single Layer will be reported (if existing).
\n By defining the geometry arg (not NULL) you can further restrict the returned report.
\n When the mode arg is set to GAIA_VECTORS_LIST_OPTIMISTIC (default) then the returned infos
will be simply retrieved from the staticized statistic tables (faster, but could be inaccurate).
\n If the mode arg is set to GAIA_VECTORS_LIST_PESSIMISTIC a preliminary attempt to update the
statistic tables will be always performed (probably slower, but surely accurate).
*/
SPATIALITE_DECLARE gaiaVectorLayersListPtr gaiaGetVectorLayersList (sqlite3
*
handle,
const
char
*table,
const
char
*geometry,
int
mode);
/**
Creates (or re-creates) the "splite_metacatalog" and
"splite_metacalog_statistics" tables.
\param handle SQLite handle to current DB connection.
\return 0 (FALSE) on failure, any other value (TRUE) on success
\sa gaiaUpdateMetaCatalogStatistics, gaiaUpdateMetaCatalogStatisticsFromMaster
*/
SPATIALITE_DECLARE int gaiaCreateMetaCatalogTables (sqlite3 * handle);
/**
Updates the "splite_metacatalog_statistics" table.
\param handle SQLite handle to current DB connection.
\param table name of the table to be processed.
\param column name of the column to be processed.
\return 0 (FALSE) on failure, any other value (TRUE) on success
\sa gaiaCreateMetaCatalogTables, gaiaUpdateMetaCatalogStatisticsFromMaster
*/
SPATIALITE_DECLARE int gaiaUpdateMetaCatalogStatistics (sqlite3 * handle,
const char *table,
const char *column);
/**
Updates the "splite_metacatalog_statistics" table (using a Master Table).
\param handle SQLite handle to current DB connection.
\param master_table name of the master-table controlling the whole process.
\param table_name name of the column into the master-table containing table-names.
\param column_name name of the column into the master-table containing column-names.
\return 0 (FALSE) on failure, any other value (TRUE) on success
\sa gaiaCreateMetaCatalogTables, gaiaUpdateMetaCatalogStatistics
*/
SPATIALITE_DECLARE int gaiaUpdateMetaCatalogStatisticsFromMaster (sqlite3 *
handle,
const char
*master_table,
const char
*table_name,
const char
*column_name);
/**
Destroys a VectorLayersList object
\param ptr pointer to the VectorLayersList object to be destroyed
\sa gaiaGetVectorLayersList
*/
SPATIALITE_DECLARE void gaiaFreeVectorLayersList (gaiaVectorLayersListPtr
ptr);
/**
Drops a layer-table, removing any related dependency
\param sqlite handle to current DB connection
\param table name of the table to be removed
\note this function will drop a SpatialTable, SpatialView or VirtualShape being
properly registered within the Metadata tables.
\n an eventual Spatial Index will be dropped as well, and any row referring the
selected table will be removed from the Metadata tables.
\return 0 on failure, any other value on success
\sa gaiaDropTableEx, gaiaRenameTable, gaiaRenameColumn
\note this one simply is a convenience method alway defaulting to
gaiaDropTableEx(sqlite, "main", table);
*/
SPATIALITE_DECLARE int gaiaDropTable (sqlite3 * sqlite, const char *table);
/**
Drops a layer-table, removing any related dependency
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param table name of the table to be removed
\note this function will drop a SpatialTable, SpatialView or VirtualShape being
properly registered within the Metadata tables.
\n an eventual Spatial Index will be dropped as well, and any row referring the
selected table will be removed from the Metadata tables.
\return 0 on failure, any other value on success
\sa gaiaDropTableEx2, gaiaRenameTable, gaiaRenameColumn
*/
SPATIALITE_DECLARE int gaiaDropTableEx (sqlite3 * sqlite,
const char *prefix,
const char *table);
/**
Drops a layer-table, removing any related dependency
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param table name of the table to be removed
\param transaction boolena; if set to TRUE will internally handle
a SQL Transaction
\note this function will drop a SpatialTable, SpatialView or VirtualShape being
properly registered within the Metadata tables.
\n an eventual Spatial Index will be dropped as well, and any row referring the
selected table will be removed from the Metadata tables.
\return 0 on failure, any other value on success
\sa gaiaDropTable, gaiaRenameTable, gaiaRenameColumn
*/
SPATIALITE_DECLARE int gaiaDropTableEx2 (sqlite3 * sqlite,
const char *prefix,
const char *table,
int transaction);
/**
Drops a layer-table, removing any related dependency
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param table name of the table to be removed
\param transaction boolean; if set to TRUE will internally handle
a SQL Transaction
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\note this function will drop a SpatialTable, SpatialView or VirtualShape being
properly registered within the Metadata tables.
\n an eventual Spatial Index will be dropped as well, and any row referring the
selected table will be removed from the Metadata tables.
\n an eventual diagnostic message pointed by error_message must be
freed by calling sqlite3_free()
\return 0 on failure, any other value on success
\sa gaiaDropTable5, gaiaRenameTable, gaiaRenameColumn
\deprecated use gaiaDropTable5() as a full replacement
*/
SPATIALITE_DECLARE int gaiaDropTableEx3 (sqlite3 * sqlite,
const char *prefix,
const char *table,
int transaction,
char **error_message);
/**
Drops a layer-table, removing any related dependency
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param table name of the table or view to be dropped
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\note this function will drop a SpatialTable, SpatialView or VirtualShape being
properly registered within the Metadata tables.
\n an eventual Spatial Index will be dropped as well, and any row referring the
selected table will be removed from the Metadata tables.
\n an eventual diagnostic message pointed by error_message must be
freed by calling sqlite3_free()
\return 0 on failure, any other value on success
\sa gaiaDropTableEx3, gaiaRenameTable, gaiaRenameColumn
*/
SPATIALITE_DECLARE int gaiaDropTable5 (sqlite3 * sqlite,
const char *prefix,
const char *table,
char **error_message);
/**
Renames a Table
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param old_name current name of the table to be renamed
(always expected to be in the MAIN database).
\param new_name new table name to be set
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\note this function will corretly rename a SpatialTable being properly
registered within the Metadata tables.
\n all triggers, Spatial Index and alike will be correctly recovered.
\n an eventual diagnostic message pointed by error_message must be
freed by calling sqlite3_free()
\return 0 on failure, any other value on success
\sa gaiaDropTable, gaiaRenameColumn
\note SQLite 3.25 (or later) is stricly required.
*/
SPATIALITE_DECLARE int gaiaRenameTable (sqlite3 * sqlite,
const char *prefix,
const char *old_name,
const char *new_name,
char **error_message);
/**
Renames a Table's Column
\param sqlite handle to current DB connection
\param prefix schema prefix identifying the target DB\n
"main" always identifies the main DB (primary, not Attached).
\param table name of the table containing the column to be renamed
(always expected to be in the MAIN database).
\param old_name current name of the column to be renamed
\param new_name new column name to be set
\param error_message: will point to a diagnostic error message
in case of failure, otherwise NULL
\note this function will corretly rename a Geometry Column being properly
registered within the Metadata tables.
\n all triggers, Spatial Index and alike will be correctly recovered.
\n an eventual diagnostic message pointed by error_message must be
freed by calling sqlite3_free()
\return 0 on failure, any other value on success
\sa gaiaDropTable, gaiaRenameTable
\note SQLite 3.25 (or later) is stricly required.
*/
SPATIALITE_DECLARE int gaiaRenameColumn (sqlite3 * sqlite,
const char *prefix,
const char *table,
const char *old_name,
const char *new_name,
char **error_message);
/**
Checks a Geometry Column for validity
\param sqlite handle to current DB connection
\param table name of the table
\param geometry name of the column to be checked
\param report_path pathname of the report-file
\param n_rows if this variable is not NULL on successful completion will
contain the total number of rows found into the checkeck table
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found into the checkeck table
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa check_geometry_column_r, check_all_geometry_columns,
sanitize_geometry_column, sanitize_all_geometry_columns
\note this function will check a Geometry Column (layer) for validity;
a HTML report will be produced.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
not reentrant and thread unsafe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int check_geometry_column (sqlite3 * sqlite,
const char *table,
const char *geom,
const char *report_path,
int *n_rows, int *n_invalids,
char **err_msg);
/**
Checks a Geometry Column for validity
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param sqlite handle to current DB connection
\param table name of the table
\param geometry name of the column to be checked
\param report_path pathname of the report-file
\param n_rows if this variable is not NULL on successful completion will
contain the total number of rows found into the checkeck table
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found into the checkeck table
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa check_geometry_column, check_all_geometry_columns,
sanitize_geometry_column, sanitize_all_geometry_columns
\note this function will check a Geometry Column (layer) for validity;
a HTML report will be produced.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
reentrant and thread-safe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int check_geometry_column_r (const void *p_cache,
sqlite3 * sqlite,
const char *table,
const char *geom,
const char *report_path,
int *n_rows,
int *n_invalids,
char **err_msg);
/**
Checks all Geometry Columns for validity
\param sqlite handle to current DB connection
\param output_dir pathname of the directory to be created for report-files
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa check_all_geometry_columns_r, check_geometry_column,
sanitize_geometry_column, sanitize_all_geometry_columns
\note this function will check all Geometry Columns (vector layers) for validity;
a HTML report will be produced.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
not reentrant and thread unsafe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int check_all_geometry_columns (sqlite3 * sqlite,
const char *output_dir,
int *n_invalids,
char **err_msg);
/**
Checks all Geometry Columns for validity
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param sqlite handle to current DB connection
\param output_dir pathname of the directory to be created for report-files
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa check_all_geometry_columns, check_geometry_column,
sanitize_geometry_column, sanitize_all_geometry_columns
\note this function will check all Geometry Columns (vector layers) for validity;
a HTML report will be produced.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
reentrant and thread-safe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int check_all_geometry_columns_r (const void *p_cache,
sqlite3 * sqlite,
const char *output_dir,
int *n_invalids,
char **err_msg);
/**
Sanitizes a Geometry Column making all invalid geometries to be valid
\param sqlite handle to current DB connection
\param table name of the table
\param geometry name of the column to be checked
\param tmp_table name of the temporary table
\param report_path pathname of the report-file
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found into the sanitize table
\param n_repaired if this variable is not NULL on successful completion will
contain the total number of repaired Geometries
\param n_discarded if this variable is not NULL on successful completion will
contain the total number of repaired Geometries (by discarding fragments)
\param n_failures if this variable is not NULL on successful completion will
contain the total number of repair failures (i.e. Geometries beyond possible repair)
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa sanitize_geometry_column_r, check_geometry_column,
check_all_geometry_columns, sanitize_all_geometry_columns
\note this function will attempt to make valid all invalid geometries
found within a Geometry Column (layer); a temporary table is required.
\n if the process has full success the temprary table will be deleted;
otherwise it will be preserved for further inspection.
a HTML report will be produced as well.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
not reentrant and thread unsafe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int sanitize_geometry_column (sqlite3 * sqlite,
const char *table,
const char *geom,
const char *tmp_table,
const char *report_path,
int *n_invalids,
int *n_repaired,
int *n_discarded,
int *n_failures,
char **err_msg);
/**
Sanitizes a Geometry Column making all invalid geometries to be valid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param sqlite handle to current DB connection
\param table name of the table
\param geometry name of the column to be checked
\param tmp_table name of the temporary table
\param report_path pathname of the report-file
\param n_invalids if this variable is not NULL on successful completion will
contain the total number of invalid Geometries found into the sanitize table
\param n_repaired if this variable is not NULL on successful completion will
contain the total number of repaired Geometries
\param n_discarded if this variable is not NULL on successful completion will
contain the total number of repaired Geometries (by discarding fragments)
\param n_failures if this variable is not NULL on successful completion will
contain the total number of repair failures (i.e. Geometries beyond possible repair)
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa sanitize_geometry_column, check_geometry_column,
check_all_geometry_columns, sanitize_all_geometry_columns
\note this function will attempt to make valid all invalid geometries
found within a Geometry Column (layer); a temporary table is required.
\n if the process has full success the temprary table will be deleted;
otherwise it will be preserved for further inspection.
a HTML report will be produced as well.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
reentrant and thread-safe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int sanitize_geometry_column_r (const void *p_cache,
sqlite3 * sqlite,
const char *table,
const char *geom,
const char *tmp_table,
const char *report_path,
int *n_invalids,
int *n_repaired,
int *n_discarded,
int *n_failures,
char **err_msg);
/**
Sanitizes all Geometry Columns making all invalid geometries to be valid
\param sqlite handle to current DB connection
\param tmp_prefix name-prefix for temporary tables
\param output_dir pathname of the directory to be created for report-files
\param not_repaired if this variable is not NULL on successful completion will
contain the total count of repair failures (i.e. Geometries beyond possible repair)
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa sanitize_all_geometry_columns_r, check_geometry_column,
check_all_geometry_columns, sanitize_geometry_column
\note this function will attempt to make valid all invalid geometries
found within all Geometry Columns (vector layers); a temporary table is
required so to support each input table.
\n if the process has full success the temprary table will be deleted;
otherwise it will be preserved for further inspection.
a HTML report will be produced as well.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
not reentrant and thread unsafe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int sanitize_all_geometry_columns (sqlite3 * sqlite,
const char
*tmp_prefix,
const char
*output_dir,
int *not_repaired,
char **err_msg);
/**
Sanitizes all Geometry Columns making all invalid geometries to be valid
\param p_cache a memory pointer returned by spatialite_alloc_connection()
\param sqlite handle to current DB connection
\param tmp_prefix name-prefix for temporary tables
\param output_dir pathname of the directory to be created for report-files
\param not_repaired if this variable is not NULL on successful completion will
contain the total count of repair failures (i.e. Geometries beyond possible repair)
\param err_msg if this variable is not NULL and the return status is ZERO
(failure), an appropriate error message will be returned
\sa sanitize_all_geometry_columns, check_geometry_column,
check_all_geometry_columns, sanitize_geometry_column
\note this function will attempt to make valid all invalid geometries
found within all Geometry Columns (vector layers); a temporary table is
required so to support each input table.
\n if the process has full success the temprary table will be deleted;
otherwise it will be preserved for further inspection.
a HTML report will be produced as well.
\n an eventual error message returned via err_msg requires to be deallocated
by invoking free()\n
reentrant and thread-safe.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int sanitize_all_geometry_columns_r (const void *p_cache,
sqlite3 * sqlite,
const char
*tmp_prefix,
const char
*output_dir,
int *not_repaired,
char **err_msg);
/**
Will precisely cut the input dataset against polygonal blade(s)
and will consequently create and populate an output dataset
\param db_handle handle to the current SQLite connection
\param cache a memory pointer returned by spatialite_alloc_connection()
\param in_db_prefix prefix of the database where the input table
is expected to be found. if NULL then "MAIN" will be assumed.
\param input_table name of the input table to be processed.
\param input_geometry name of the input table Geometry column;
it could be NULL and in this case the appropriate column name will
be automatically determind. anyway if the input table do contains
two or more Geometries passing a NULL geometry name will raise a
fatal error.
\param blade_db_prefix prefix of the database where the "blade" table
is expected to be found. if NULL then "MAIN" will be assumed.
\param blade_table name of the table expected to contain Polygons
or MultiPolygon Geometries acting as blades.
\param blade_geometry name of the "blade" table Geometry column;
it could be NULL and in this case the appropriate column name will
be automatically determind. anyway if the input table do contains
two or more Geometries passing a NULL geometry name will raise a
fatal error.
\param output_table name to assinged to the destination table intended
to permanently store all results. this table must non exists.
\param transaction boolean; if set to TRUE will internally handle
a SQL Transaction.
\param ram_tmp_store boolean: if set to TRUE all TEMPORARY tables
and indices will be created in RAM, otherwise in a file.
\param message pointer to a string buffer; if not NULL it will point
on completion an eventual error message.
\return 0 on failure, any other value on success
\note the message buffer if not NULL will point to a dymanic memory
allocation and is expected to be released by calling sqlite3_free()
*/
SPATIALITE_DECLARE int gaiaCutter (sqlite3 * db_handle, const void *cache,
const char *in_db_prefix,
const char *input_table,
const char *input_geom,
const char *blade_db_prefix,
const char *blade_table,
const char *blade_geom,
const char *output_table,
int transaction, int ram_tmp_store,
char **message);
/**
Will attempt to create the Routing Nodes columns for a spatial table
\param db_handle handle to the current SQLite connection
\param cache a memory pointer returned by spatialite_alloc_connection()
\param prefix schema prefix identifying the target DB (could be
eventually NULL)\n
\param table name of the table to be processed.
\param geom_column name of the table column containing Linestring Geometries
(could be eventually NULL).
\param from_column name of the table column where NodeFrom values
will be stored.
\param to_column name of the column where ToFrom values
will be stored.
\return 0 on failure, any other value on success
*/
SPATIALITE_DECLARE int gaia_create_routing_nodes (sqlite3 * db_handle,
const void *cache,
const char *prefix,
const char *table,
const char *geom_column,
const char *from_column,
const char *to_column);
/**
Will attempt to create a VirtualRouting from an input table
\param db_handle handle to the current SQLite connection
\param cache a memory pointer returned by spatialite_alloc_connection()
\param routing_data_table name of the Routing Data Table to be created.
\param virtual_routing_table name of the VirtualRouting Table to be created.
\param input_table name of the input table to be processed.
\param from_column name of the input table column containing NodeFrom.
\param to_column name of the input table column containing NodeTo.
\param geom_column name of the input table column containing Linestring Geometries
(could be eventually NULL).
\param cost_column name of the input table column containing Cost values
(could be eventually NULL).
\param name_column name of the input table column containing RoadName
(could be eventually NULL).
\param a_star_enabled if set to TRUE the Routing Data Table will support
both Djiskra's Shortest Path and A* algorithms; if set to FALSE only
the Djiskra's algorithm will be supported.
\param bidirectional if set to TRUE all input arcs/links will be assumed
to be bidirectional (from-to and to-from); if set to FALSE all input
arcs/links will be assumed to be unidirectional (from-to only).
\param oneway_from name of the input table column containing OneWayFrom
(could be eventually NULL).
\param oneway_to name of the input table column containing OneWayTo
(could be eventually NULL).
\param overwrite if set to TRUE both the Routing Data Table and the
VirtualRouting Table will be dropped if already existing; if set to
FALSE an already existing Routing Data Table or VirtualRouting Table
will cause a fatal error.
\return 0 on failure, any other value on success
\note at least one between geom_column and cost_column shall not be NULL.
both oneway_from and oneway_to must be NULL or must contain a valid
column name; mixing a column name and a NULL will be considered a
fatal error.
*/
SPATIALITE_DECLARE int gaia_create_routing (sqlite3 * db_handle,
const void *cache,
const char *routing_data_table,
const char
*virtual_routing_table,
const char *input_table,
const char *from_column,
const char *to_column,
const char *geom_column,
const char *cost_column,
const char *name_column,
int a_star_enabled,
int bidirectional,
const char *oneway_from,
const char *oneway_to,
int overwrite);
SPATIALITE_DECLARE const char *gaia_create_routing_get_last_error (const
void
*cache);
SPATIALITE_DECLARE int gaiaGPKG2Spatialite (sqlite3 * handle_in,
const char *gpkg_in_path,
sqlite3 * handle_out,
const char *splite_out_path);
SPATIALITE_DECLARE int gaiaSpatialite2GPKG (sqlite3 * handle_in,
const char *splite_in_path,
sqlite3 * handle_out,
const char *gpkg_out_path);
SPATIALITE_DECLARE const void *gaiaGetCurrentProjContext (const void
*cache);
SPATIALITE_DECLARE int gaiaSetCurrentCachedProj (const void
*cache, void *pj,
const char *proj_string_1,
const char *proj_string_2,
void *area);
SPATIALITE_DECLARE void *gaiaGetCurrentCachedProj (const void *cache);
SPATIALITE_DECLARE int gaiaCurrentCachedProjMatches (const void *cache,
const char
*proj_string_1,
const char
*proj_string_2,
void *area);
SPATIALITE_DECLARE char *gaiaGetDbObjectScope (sqlite3 * handle,
const char *db_prefix,
const char *obj_name);
#ifdef __cplusplus
}
#endif
#endif /* _SPATIALITE_H */
libspatialite-5.1.0/src/headers/spatialite_private.h 0000644 0001750 0001750 00000137012 14463127014 017536 0000000 0000000 /*
spatialite.h -- Gaia spatial support for SQLite
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include "spatialite/gg_sequence.h"
#include "spatialite/sqlite.h"
/**
\file spatialite_private.h
SpatiaLite private header file
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef _WIN32
#ifdef DLL_EXPORT
#define SPATIALITE_PRIVATE
#else
#define SPATIALITE_PRIVATE
#endif
#else
#define SPATIALITE_PRIVATE __attribute__ ((visibility("hidden")))
#endif
#endif
#ifndef _SPATIALITE_PRIVATE_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _SPATIALITE_PRIVATE_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/** spatial_ref_sys_init2: will create the "spatial_ref_sys" table
and will populate this table with any supported EPSG SRID definition */
#define GAIA_EPSG_ANY -9999
/** spatial_ref_sys_init2: will create the "spatial_ref_sys" table
and will populate this table only inserting WGS84-related definitions */
#define GAIA_EPSG_WGS84_ONLY -9998
/** spatial_ref_sys_init2: will create the "spatial_ref_sys" table
but will avoid to insert any row at all */
#define GAIA_EPSG_NONE -9997
#define SPATIALITE_STATISTICS_GENUINE 1
#define SPATIALITE_STATISTICS_VIEWS 2
#define SPATIALITE_STATISTICS_VIRTS 3
#define SPATIALITE_STATISTICS_LEGACY 4
#define SPATIALITE_CACHE_MAGIC1 0xf8
#define SPATIALITE_CACHE_MAGIC2 0x8f
#define MULTIPLE_POINTS_TABLE 0x10
#define MULTIPLE_POINTS_POINT 0x20
#define MULTIPLE_POINTS_PK 0x40
#define MULTIPLE_POINTS_POS 0x80
#define MULTIPLE_POINTS_NOGEOM 0x41
#define MULTIPLE_POINTS_SRID 0x42
#define MULTIPLE_POINTS_NOPOINT 0x44
#define MULTIPLE_POINTS_DIMS 0x48
#define MULTIPLE_POINTS_SQL 0x81
#define MULTIPLE_POINTS_DUPL 0x82
#define MULTIPLE_POINTS_GEOM 0x84
#define MULTIPLE_POINTS_OK 0xff
struct vxpath_ns
{
/* a Namespace definition */
char *Prefix;
char *Href;
struct vxpath_ns *Next;
};
struct vxpath_namespaces
{
/* Namespace container */
struct vxpath_ns *First;
struct vxpath_ns *Last;
};
struct splite_geos_cache_item
{
unsigned char gaiaBlob[64];
int gaiaBlobSize;
uLong crc32;
void *geosGeom;
void *preparedGeosGeom;
};
struct splite_xmlSchema_cache_item
{
time_t timestamp;
char *schemaURI;
void *schemaDoc;
void *parserCtxt;
void *schema;
};
struct splite_savepoint
{
char *savepoint_name;
struct splite_savepoint *prev;
struct splite_savepoint *next;
};
struct splite_vtable_extent
{
char *table;
double minx;
double maxx;
double miny;
double maxy;
int srid;
struct splite_vtable_extent *prev;
struct splite_vtable_extent *next;
};
struct gaia_variant_value
{
/* a struct/union intended to store a SQLite Variant Value */
int dataType; /* one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT or SQLITE_BLOB */
sqlite3_int64 intValue;
double dblValue;
char *textValue;
unsigned char *blobValue;
int size;
};
#define MAX_XMLSCHEMA_CACHE 16
struct splite_internal_cache
{
unsigned char magic1;
int gpkg_mode;
int gpkg_amphibious_mode;
int decimal_precision;
void *GEOS_handle;
void *PROJ_handle;
void *RTTOPO_handle;
void *xmlParsingErrors;
void *xmlSchemaValidationErrors;
void *xmlXPathErrors;
char *cutterMessage;
char *storedProcError;
char *createRoutingError;
struct splite_geos_cache_item cacheItem1;
struct splite_geos_cache_item cacheItem2;
struct splite_xmlSchema_cache_item xmlSchemaCache[MAX_XMLSCHEMA_CACHE];
int pool_index;
void (*geos_warning) (const char *fmt, ...);
void (*geos_error) (const char *fmt, ...);
char *gaia_geos_error_msg;
char *gaia_geos_warning_msg;
char *gaia_geosaux_error_msg;
char *gaia_rttopo_error_msg;
char *gaia_rttopo_warning_msg;
char *gaia_proj_error_msg;
int silent_mode;
void *firstTopology;
void *lastTopology;
void *firstNetwork;
void *lastNetwork;
unsigned int next_topo_savepoint;
struct splite_savepoint *first_topo_svpt;
struct splite_savepoint *last_topo_svpt;
unsigned int next_network_savepoint;
struct splite_savepoint *first_net_svpt;
struct splite_savepoint *last_net_svpt;
gaiaSequencePtr first_seq;
gaiaSequencePtr last_seq;
struct splite_vtable_extent *first_vtable_extent;
struct splite_vtable_extent *last_vtable_extent;
int ok_last_used_sequence;
int last_used_sequence_val;
char *SqlProcLogfile;
int SqlProcLogfileAppend;
FILE *SqlProcLog;
int SqlProcContinue;
struct gaia_variant_value *SqlProcRetValue;
int tinyPointEnabled;
unsigned char magic2;
char *lastPostgreSqlError;
int buffer_end_cap_style;
int buffer_join_style;
double buffer_mitre_limit;
int buffer_quadrant_segments;
int proj6_cached;
void *proj6_cached_pj;
char *proj6_cached_string_1;
char *proj6_cached_string_2;
void *proj6_cached_area;
int is_pause_enabled;
};
struct epsg_defs
{
int srid;
char *auth_name;
int auth_srid;
char *ref_sys_name;
char *proj4text;
char *srs_wkt;
int is_geographic;
int flipped_axes;
char *spheroid;
char *prime_meridian;
char *datum;
char *projection;
char *unit;
char *axis_1;
char *orientation_1;
char *axis_2;
char *orientation_2;
struct epsg_defs *next;
};
struct gaia_control_points
{
/* a struct to implement ATM_ControlPoints - aggregate function */
int count;
int allocation_incr;
int allocated_items;
int has3d;
int tps;
int order;
/* point set A */
double *x0;
double *y0;
double *z0;
/* point set B */
double *x1;
double *y1;
double *z1;
/* affine transform coefficients */
double a;
double b;
double c;
double d;
double e;
double f;
double g;
double h;
double i;
double xoff;
double yoff;
double zoff;
int affine_valid;
};
SPATIALITE_PRIVATE void free_internal_cache (struct splite_internal_cache
*cache);
SPATIALITE_PRIVATE void free_internal_cache_topologies (void *first);
SPATIALITE_PRIVATE void free_internal_cache_networks (void *first);
SPATIALITE_PRIVATE struct epsg_defs *add_epsg_def (int filter_srid,
struct epsg_defs
**first,
struct epsg_defs
**last, int srid,
const char *auth_name,
int auth_srid,
const char
*ref_sys_name);
SPATIALITE_PRIVATE struct epsg_defs *add_epsg_def_ex (int filter_srid,
struct epsg_defs
**first,
struct epsg_defs
**last, int srid,
const char
*auth_name,
int auth_srid,
const char
*ref_sys_name,
int is_geographic,
int flipped_axes,
const char
*spheroid,
const char
*prime_meridian,
const char *datum,
const char
*projection,
const char *unit,
const char *axis_1,
const char
*orientation_1,
const char *axis_2,
const char
*orientation_2);
SPATIALITE_PRIVATE void add_proj4text (struct epsg_defs *p, int count,
const char *text);
SPATIALITE_PRIVATE void add_srs_wkt (struct epsg_defs *p, int count,
const char *text);
SPATIALITE_PRIVATE void initialize_epsg (int filter,
struct epsg_defs **first,
struct epsg_defs **last);
SPATIALITE_PRIVATE void free_epsg (struct epsg_defs *first);
SPATIALITE_PRIVATE int exists_spatial_ref_sys (void *handle);
SPATIALITE_PRIVATE int checkSpatialMetaData (const void *sqlite);
SPATIALITE_PRIVATE int checkSpatialMetaData_ex (const void *sqlite,
const char *db_prefix);
SPATIALITE_PRIVATE int delaunay_triangle_check (void *pg);
SPATIALITE_PRIVATE void *voronoj_build (int pgs, void *first,
double extra_frame_size);
SPATIALITE_PRIVATE void *voronoj_build_r (const void *p_cache, int pgs,
void *first,
double extra_frame_size);
SPATIALITE_PRIVATE void *voronoj_export (void *voronoj, void *result,
int only_edges);
SPATIALITE_PRIVATE void *voronoj_export_r (const void *p_cache,
void *voronoj, void *result,
int only_edges);
SPATIALITE_PRIVATE void voronoj_free (void *voronoj);
SPATIALITE_PRIVATE void *concave_hull_build (void *first,
int dimension_model,
double factor,
int allow_holes);
SPATIALITE_PRIVATE void *concave_hull_build_r (const void *p_cache,
void *first,
int dimension_model,
double factor,
int allow_holes);
SPATIALITE_PRIVATE int createAdvancedMetaData (void *sqlite);
SPATIALITE_PRIVATE void updateSpatiaLiteHistory (void *sqlite,
const char *table,
const char *geom,
const char *operation);
SPATIALITE_PRIVATE int createGeometryColumns (void *p_sqlite);
SPATIALITE_PRIVATE int createTemporarySpatialRefSys (void *p_sqlite,
const char *db_prefix);
SPATIALITE_PRIVATE int createTemporaryGeometryColumns (void *p_sqlite,
const char
*db_prefix);
SPATIALITE_PRIVATE int check_layer_statistics (void *p_sqlite);
SPATIALITE_PRIVATE int check_views_layer_statistics (void *p_sqlite);
SPATIALITE_PRIVATE int check_virts_layer_statistics (void *p_sqlite);
SPATIALITE_PRIVATE void updateGeometryTriggers (void *p_sqlite,
const char *table,
const char *column);
SPATIALITE_PRIVATE void updateTemporaryGeometryTriggers (void *p_sqlite,
const char
*db_prefix,
const char *table,
const char
*column);
SPATIALITE_PRIVATE int upgradeGeometryTriggers (void *p_sqlite);
SPATIALITE_PRIVATE int getRealSQLnames (void *p_sqlite, const char *table,
const char *column,
char **real_table,
char **real_column);
SPATIALITE_PRIVATE int getRealSQLnamesTemporary (void *p_sqlite,
const char *db_prefix,
const char *table,
const char *column,
char **real_table,
char **real_column);
/* DEPRECATED - always use buildSpatialIndexEx */
SPATIALITE_PRIVATE void buildSpatialIndex (void *p_sqlite,
const unsigned char *table,
const char *column);
SPATIALITE_PRIVATE int buildSpatialIndexEx (void *p_sqlite,
const unsigned char *table,
const char *column);
SPATIALITE_PRIVATE int buildTemporarySpatialIndex (void *p_sqlite,
const char *db_prefix,
const unsigned char
*table,
const char *column);
SPATIALITE_PRIVATE int validateRowid (void *p_sqlite, const char *table);
SPATIALITE_PRIVATE int validateTemporaryRowid (void *p_sqlite,
const char *db_prefix,
const char *table);
SPATIALITE_PRIVATE int doComputeFieldInfos (void *p_sqlite,
const char *table,
const char *column,
int stat_type, void *p_lyr);
SPATIALITE_PRIVATE void getProjParams (void *p_sqlite, int srid,
char **params);
SPATIALITE_PRIVATE void getProjWkt (void *p_sqlite, int srid, char **wkt);
SPATIALITE_PRIVATE void getProjAuthNameSrid (void *p_sqlite, int srid,
char **auth_name_srid);
SPATIALITE_PRIVATE int getEllipsoidParams (void *p_sqlite, int srid,
double *a, double *b,
double *rf);
SPATIALITE_PRIVATE void addVectorLayer (void *list,
const char *layer_type,
const char *table_name,
const char *geometry_column,
int geometry_type, int srid,
int spatial_index);
SPATIALITE_PRIVATE void addVectorLayerExtent (void *list,
const char *table_name,
const char *geometry_column,
int count, double min_x,
double min_y, double max_x,
double max_y);
SPATIALITE_PRIVATE void addLayerAttributeField (void *list,
const char *table_name,
const char
*geometry_column,
int ordinal,
const char *column_name,
int null_values,
int integer_values,
int double_values,
int text_values,
int blob_values,
int null_max_size,
int max_size,
int null_int_range,
void *integer_min,
void *integer_max,
int null_double_range,
double double_min,
double double_max);
SPATIALITE_PRIVATE int createStylingTables (void *p_sqlite, int relaxed);
SPATIALITE_PRIVATE int createStylingTables_ex (void *p_sqlite,
int relaxed,
int transaction);
SPATIALITE_PRIVATE int reCreateStylingTriggers (void *p_sqlite,
int relaxed,
int transaction);
SPATIALITE_PRIVATE int register_external_graphic (void *p_sqlite,
const char *xlink_href,
const unsigned char
*p_blob, int n_bytes,
const char *title,
const char *abstract,
const char *file_name);
SPATIALITE_PRIVATE int unregister_external_graphic (void *p_sqlite,
const char *xlink_href);
SPATIALITE_PRIVATE int register_vector_style (void *p_sqlite,
const unsigned char *p_blob,
int n_bytes);
SPATIALITE_PRIVATE int unregister_vector_style (void *p_sqlite,
int style_id,
const char *style_name,
int remove_all);
SPATIALITE_PRIVATE int reload_vector_style (void *p_sqlite, int style_id,
const char *style_name,
const unsigned char *p_blob,
int n_bytes);
/* DEPRECATED - always use register_vector_styled_layer_ex */
SPATIALITE_PRIVATE int register_vector_styled_layer (void *p_sqlite,
const char
*f_table_name,
const char
*f_geometry_column,
int style_id,
const unsigned char
*p_blob, int n_bytes);
SPATIALITE_PRIVATE int register_vector_styled_layer_ex (void *p_sqlite,
const char
*coverage_name,
int style_id,
const char
*style_name);
SPATIALITE_PRIVATE int unregister_vector_styled_layer (void *p_sqlite,
const char
*coverage_name,
int style_id,
const char
*style_name);
SPATIALITE_PRIVATE int register_raster_style (void *p_sqlite,
const unsigned char *p_blob,
int n_bytes);
SPATIALITE_PRIVATE int unregister_raster_style (void *p_sqlite,
int style_id,
const char *style_name,
int remove_all);
SPATIALITE_PRIVATE int reload_raster_style (void *p_sqlite, int style_id,
const char *style_name,
const unsigned char *p_blob,
int n_bytes);
/* DEPRECATED - always use register_raster_styled_layer_ex */
SPATIALITE_PRIVATE int register_raster_styled_layer (void *p_sqlite,
const char
*coverage_name,
int style_id,
const unsigned char
*p_blob, int n_bytes);
SPATIALITE_PRIVATE int register_raster_styled_layer_ex (void *p_sqlite,
const char
*coverage_name,
int style_id,
const char
*style_name);
SPATIALITE_PRIVATE int unregister_raster_styled_layer (void *p_sqlite,
const char
*coverage_name,
int style_id,
const char
*style_name);
SPATIALITE_PRIVATE int register_raster_coverage_srid (void *p_sqlite,
const char
*coverage_name,
int srid);
SPATIALITE_PRIVATE int unregister_raster_coverage_srid (void *p_sqlite,
const char
*coverage_name,
int srid);
SPATIALITE_PRIVATE int register_raster_coverage_keyword (void *p_sqlite,
const char
*coverage_name,
const char
*keyword);
SPATIALITE_PRIVATE int unregister_raster_coverage_keyword (void *p_sqlite,
const char
*coverage_name,
const char
*keyword);
SPATIALITE_PRIVATE int update_raster_coverage_extent (void *p_sqlite,
const void *cache,
const char
*coverage_name,
int transaction);
SPATIALITE_PRIVATE int register_map_configuration (void *p_sqlite,
const unsigned char
*p_blob, int n_bytes);
SPATIALITE_PRIVATE int unregister_map_configuration (void *p_sqlite,
int id,
const char *name);
SPATIALITE_PRIVATE int reload_map_configuration (void *p_sqlite, int id,
const char *name,
const unsigned char
*p_blob, int n_bytes);
SPATIALITE_PRIVATE int count_map_configurations (void *p_sqlite);
SPATIALITE_PRIVATE char *get_map_configuration_name (void *p_sqlite,
int ind);
SPATIALITE_PRIVATE char *get_map_configuration_title (void *p_sqlite,
int ind);
SPATIALITE_PRIVATE char *get_map_configuration_abstract (void *p_sqlite,
int ind);
SPATIALITE_PRIVATE int createIsoMetadataTables (void *p_sqlite,
int relaxed);
SPATIALITE_PRIVATE int recreateIsoMetaRefsTriggers (void *p_sqlite,
int enable_eval);
SPATIALITE_PRIVATE int get_iso_metadata_id (void *p_sqlite,
const char *fileIdentifier,
void *p_id);
SPATIALITE_PRIVATE int register_iso_metadata (void *p_sqlite,
const char *scope,
const unsigned char *p_blob,
int n_bytes, void *p_id,
const char *fileIdentifier);
SPATIALITE_PRIVATE int createRasterCoveragesTable (void *p_sqlite);
SPATIALITE_PRIVATE int reCreateRasterCoveragesTriggers (void *p_sqlite);
SPATIALITE_PRIVATE int checkPopulatedCoverage (void *p_sqlite,
const char *db_prefix,
const char *coverage_name);
SPATIALITE_PRIVATE int createVectorCoveragesTable (void *p_sqlite);
SPATIALITE_PRIVATE int reCreateVectorCoveragesTriggers (void *p_sqlite);
SPATIALITE_PRIVATE int register_vector_coverage (void *p_sqlite,
const char
*coverage_name,
const char *f_table_name,
const char
*f_geometry_column,
const char *title,
const char *abstract,
int is_queryable,
int is_editable);
SPATIALITE_PRIVATE int register_spatial_view_coverage (void *p_sqlite,
const char
*coverage_name,
const char
*view_name,
const char
*view_geometry,
const char *title,
const char *abstract,
int is_queryable,
int is_editable);
SPATIALITE_PRIVATE int register_virtual_table_coverage (void *p_sqlite,
const char
*coverage_name,
const char
*virt_name,
const char
*virt_geometry,
const char *title,
const char
*abstract,
int is_queryable);
SPATIALITE_PRIVATE int register_topogeo_coverage (void *p_sqlite,
const char
*coverage_name,
const char *topogeo_name,
const char *title,
const char *abstract,
int is_queryable,
int is_editable);
SPATIALITE_PRIVATE int register_toponet_coverage (void *p_sqlite,
const char
*coverage_name,
const char *toponet_name,
const char *title,
const char *abstract,
int is_queryable,
int is_editable);
SPATIALITE_PRIVATE int unregister_vector_coverage (void *p_sqlite,
const char
*coverage_name);
SPATIALITE_PRIVATE int set_vector_coverage_infos (void *p_sqlite,
const char
*coverage_name,
const char *title,
const char *abstract,
int is_queryable,
int is_editable);
SPATIALITE_PRIVATE int set_vector_coverage_copyright (void *p_sqlite,
const char
*coverage_name,
const char *copyright,
const char *license);
SPATIALITE_PRIVATE int set_vector_coverage_visibility_range (void *p_sqlite,
const char
*coverage_name,
double
min_scale,
double
max_scale);
SPATIALITE_PRIVATE int register_vector_coverage_srid (void *p_sqlite,
const char
*coverage_name,
int srid);
SPATIALITE_PRIVATE int unregister_vector_coverage_srid (void *p_sqlite,
const char
*coverage_name,
int srid);
SPATIALITE_PRIVATE int register_vector_coverage_keyword (void *p_sqlite,
const char
*coverage_name,
const char
*keyword);
SPATIALITE_PRIVATE int unregister_vector_coverage_keyword (void *p_sqlite,
const char
*coverage_name,
const char
*keyword);
SPATIALITE_PRIVATE int update_vector_coverage_extent (void *p_sqlite,
const void *cache,
const char
*coverage_name,
int transaction);
SPATIALITE_PRIVATE int createWMSTables (void *p_sqlite);
SPATIALITE_PRIVATE int register_wms_getcapabilities (void *p_sqlite,
const char *url,
const char *title,
const char *abstract);
SPATIALITE_PRIVATE int unregister_wms_getcapabilities (void *p_sqlite,
const char *url);
SPATIALITE_PRIVATE int set_wms_getcapabilities_infos (void *p_sqlite,
const char *url,
const char *title,
const char *abstract);
SPATIALITE_PRIVATE int register_wms_getmap (void *p_sqlite,
const char *getcapabilities_url,
const char *getmap_url,
const char *layer_name,
const char *title,
const char *abstract,
const char *version,
const char *ref_sys,
const char *image_format,
const char *style,
int transparent,
int flip_axes,
int tiled,
int cached,
int tile_width,
int tile_height,
const char *bgcolor,
int is_queryable,
const char *getfeatureinfo_url,
int cascaded, double min_scale,
double max_scale);
SPATIALITE_PRIVATE int unregister_wms_getmap (void *p_sqlite,
const char *url,
const char *layer_name);
SPATIALITE_PRIVATE int set_wms_getmap_infos (void *p_sqlite,
const char *url,
const char *layer_name,
const char *title,
const char *abstract);
SPATIALITE_PRIVATE int set_wms_getmap_copyright (void *p_sqlite,
const char *url,
const char *layer_name,
const char *copyright,
const char *license);
SPATIALITE_PRIVATE int set_wms_getmap_bgcolor (void *p_sqlite,
const char *url,
const char *layer_name,
const char *bgcolor);
SPATIALITE_PRIVATE int set_wms_getmap_queryable (void *p_sqlite,
const char *url,
const char *layer_name,
int is_queryable,
const char
*getfeatureifo_url);
SPATIALITE_PRIVATE int set_wms_getmap_options (void *p_sqlite,
const char *url,
const char *layer_name,
int transparent,
int flip_axes);
SPATIALITE_PRIVATE int set_wms_getmap_tiled (void *p_sqlite,
const char *url,
const char *layer_name,
int tiled, int cached,
int tile_width,
int tile_height);
SPATIALITE_PRIVATE int register_wms_setting (void *p_sqlite,
const char *url,
const char *layer_name,
const char *key,
const char *value,
int is_default);
SPATIALITE_PRIVATE int unregister_wms_setting (void *p_sqlite,
const char *url,
const char *layer_name,
const char *key,
const char *value);
SPATIALITE_PRIVATE int set_wms_default_setting (void *p_sqlite,
const char *url,
const char *layer_name,
const char *key,
const char *value);
SPATIALITE_PRIVATE int register_wms_style (void *p_sqlite,
const char *url,
const char *layer_name,
const char *style_name,
const char *style_title,
const char *style_abstract,
int is_default);
SPATIALITE_PRIVATE int register_wms_srs (void *p_sqlite,
const char *url,
const char *layer_name,
const char *ref_sys, double minx,
double miny, double maxx,
double maxy, int is_default);
SPATIALITE_PRIVATE int unregister_wms_srs (void *p_sqlite,
const char *url,
const char *layer_name,
const char *ref_sys);
SPATIALITE_PRIVATE int set_wms_default_srs (void *p_sqlite,
const char *url,
const char *layer_name,
const char *ref_sys);
SPATIALITE_PRIVATE char *wms_getmap_request_url (void *p_sqlite,
const char *getmap_url,
const char *layer_name,
int width, int height,
double minx, double miny,
double maxx, double maxy);
SPATIALITE_PRIVATE char *wms_getfeatureinfo_request_url (void *p_sqlite,
const char
*getmap_url,
const char
*layer_name,
int width,
int height, int x,
int y, double minx,
double miny,
double maxx,
double maxy,
int feature_count);
SPATIALITE_PRIVATE int register_data_license (void *p_sqlite,
const char *license_name,
const char *url);
SPATIALITE_PRIVATE int unregister_data_license (void *p_sqlite,
const char *license_name);
SPATIALITE_PRIVATE int rename_data_license (void *p_sqlite,
const char *old_name,
const char *new_name);
SPATIALITE_PRIVATE int set_data_license_url (void *p_sqlite,
const char *license_name,
const char *url);
SPATIALITE_PRIVATE const char *splite_rttopo_version (void);
SPATIALITE_PRIVATE void splite_free_geos_cache_item (struct
splite_geos_cache_item
*p);
SPATIALITE_PRIVATE void splite_free_geos_cache_item_r (const void
*p_cache,
struct
splite_geos_cache_item
*p);
SPATIALITE_PRIVATE void splite_free_xml_schema_cache_item (struct
splite_xmlSchema_cache_item
*p);
SPATIALITE_PRIVATE void vxpath_free_namespaces (struct vxpath_namespaces
*ns_list);
SPATIALITE_PRIVATE struct vxpath_namespaces *vxpath_get_namespaces (void
*p_xml_doc);
SPATIALITE_PRIVATE int vxpath_eval_expr (const void *p_cache,
void *xml_doc,
const char *xpath_expr,
void *p_xpathCtx,
void *p_xpathObj);
SPATIALITE_PRIVATE void *register_spatialite_sql_functions (void *db,
const void
*cache);
SPATIALITE_PRIVATE void init_spatialite_virtualtables (void *p_db,
const void *p_cache);
SPATIALITE_PRIVATE void spatialite_splash_screen (int verbose);
SPATIALITE_PRIVATE void geos_error (const char *fmt, ...);
SPATIALITE_PRIVATE void geos_warning (const char *fmt, ...);
SPATIALITE_PRIVATE void splite_cache_semaphore_lock (void);
SPATIALITE_PRIVATE void splite_cache_semaphore_unlock (void);
SPATIALITE_PRIVATE const void *gaiaAuxClonerCreate (const void *sqlite,
const char *db_prefix,
const char *in_table,
const char *out_table);
SPATIALITE_PRIVATE const void *gaiaAuxClonerCreateEx (const void *sqlite,
const char
*db_prefix,
const char
*in_table,
const char
*out_table,
int create_only);
SPATIALITE_PRIVATE void gaiaAuxClonerDestroy (const void *cloner);
SPATIALITE_PRIVATE void gaiaAuxClonerAddOption (const void *cloner,
const char *option);
SPATIALITE_PRIVATE int gaiaAuxClonerCheckValidTarget (const void *cloner);
SPATIALITE_PRIVATE int gaiaAuxClonerExecute (const void *cloner);
SPATIALITE_PRIVATE const void *gaiaElemGeomOptionsCreate ();
SPATIALITE_PRIVATE void gaiaElemGeomOptionsAdd (const void *options,
const char *option);
SPATIALITE_PRIVATE void gaiaElemGeomOptionsDestroy (const void *options);
SPATIALITE_PRIVATE int gaia_matrix_to_arrays (const unsigned char *blob,
int blob_sz, double *E,
double *N, double *Z);
/* Topology SQL functions */
SPATIALITE_PRIVATE void *fromRTGeom (const void *ctx, const void *rtgeom,
const int dimension_model,
const int declared_type);
SPATIALITE_PRIVATE void *toRTGeom (const void *ctx, const void *gaia);
SPATIALITE_PRIVATE void fnctaux_GetLastTopologyException (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_CreateTopoTables (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ReCreateTopoTriggers (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE int do_create_topologies (void *sqlite_handle);
SPATIALITE_PRIVATE void drop_topologies_triggers (void *sqlite_handle);
SPATIALITE_PRIVATE int do_create_topologies_triggers (void *sqlite_handle);
SPATIALITE_PRIVATE int do_create_networks (void *sqlite_handle);
SPATIALITE_PRIVATE void drop_networks_triggers (void *sqlite_handle);
SPATIALITE_PRIVATE int do_create_networks_triggers (void *sqlite_handle);
SPATIALITE_PRIVATE void fnctaux_CreateTopology (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_DropTopology (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddIsoNode (const void *context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_MoveIsoNode (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemIsoNode (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddIsoEdge (const void *context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddEdgeModFace (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddEdgeNewFaces (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemEdgeNewFace (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemEdgeModFace (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_ChangeEdgeGeom (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemIsoEdge (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddIsoEdge (const void *context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ModEdgeSplit (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_NewEdgesSplit (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_ModEdgeHeal (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_NewEdgeHeal (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetFaceEdges (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetFaceGeometry (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ValidateTopoGeo (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_CreateTopoGeo (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetNodeByPoint (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetEdgeByPoint (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetFaceByPoint (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_AddPoint (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_AddLineString (const void
*context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_AddLineStringNoFace (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_Polygonize (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_FromGeoTable (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_FromGeoTableNoFace (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_FromGeoTableExt (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_FromGeoTableNoFaceExt (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_Polygonize (const void
*context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_TopoSnap (const void
*context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_SnappedGeoTable (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_ToGeoTable (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_PolyFacesList (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_LineEdgesList (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_ToGeoTableGeneralize (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_RemoveSmallFaces (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_RemoveDanglingEdges (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_RemoveDanglingNodes (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_NewEdgeHeal (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_ModEdgeHeal (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_NewEdgesSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_ModEdgeSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_CreateTopoLayer (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_InitTopoLayer (const void
*context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_RemoveTopoLayer (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_ExportTopoLayer (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_InsertFeatureFromTopoLayer (const
void
*context,
int
argc,
const
void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_Clone (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_SubdivideLines (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_DisambiguateSegmentEdges (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_GetEdgeSeed (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_GetFaceSeed (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_UpdateSeeds (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_SnapPointToSeed (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoGeo_SnapLineToSeed (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void start_topo_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE void release_topo_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE void rollback_topo_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE void add_vtable_extent (const char *table, double minx,
double miny, double maxx,
double maxy, int srid,
const void *cache);
SPATIALITE_PRIVATE void remove_vtable_extent (const char *table,
const void *cache);
SPATIALITE_PRIVATE int get_vtable_extent (const char *table, double *minx,
double *miny, double *maxx,
double *maxy, int *srid,
const void *cache);
/* Topology-Network SQL functions */
SPATIALITE_PRIVATE void fnctaux_GetLastNetworkException (const void
*context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_CreateNetwork (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_DropNetwork (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddIsoNetNode (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_MoveIsoNetNode (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemIsoNetNode (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_AddLink (const void *context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ChangeLinkGeom (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_RemoveLink (const void *context, int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_NewLogLinkSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ModLogLinkSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_NewGeoLinkSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ModGeoLinkSplit (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_NewLinkHeal (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_ModLinkHeal (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_LogiNetFromTGeo (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_SpatNetFromTGeo (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_SpatNetFromGeom (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ValidLogicalNet (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_ValidSpatialNet (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetNetNodeByPoint (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_GetLinkByPoint (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_FromGeoTable (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_ToGeoTable (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_ToGeoTableGeneralize (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_ToGeoTableGeneralize (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_Clone (const void *context,
int argc, const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_GetLinkSeed (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_UpdateSeeds (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_DisambiguateSegmentLinks (const void
*context,
int argc,
const void
*argv);
SPATIALITE_PRIVATE void fnctaux_TopoNet_LineLinksList (const void *context,
int argc,
const void *argv);
SPATIALITE_PRIVATE void start_net_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE void release_net_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE void rollback_net_savepoint (const void *handle,
const void *cache);
SPATIALITE_PRIVATE int test_inconsistent_topology (const void *handle);
SPATIALITE_PRIVATE char *url_toUtf8 (const char *url,
const char *in_charset);
SPATIALITE_PRIVATE char *url_fromUtf8 (const char *url,
const char *out_charset);
SPATIALITE_PRIVATE int gaia_check_reference_geo_table (const void *handle,
const char
*db_prefix,
const char *table,
const char *column,
char **xtable,
char **xcolumn,
int *srid,
int *family);
SPATIALITE_PRIVATE int gaia_check_output_table (const void *handle,
const char *table);
SPATIALITE_PRIVATE int gaia_check_spatial_index (const void *handle,
const char *db_prefix,
const char *ref_table,
const char *ref_column);
SPATIALITE_PRIVATE int gaia_do_eval_disjoint (const void *handle,
const char *matrix);
SPATIALITE_PRIVATE int gaia_do_eval_overlaps (const void *handle,
const char *matrix);
SPATIALITE_PRIVATE int gaia_do_eval_covers (const void *handle,
const char *matrix);
SPATIALITE_PRIVATE int gaia_do_eval_covered_by (const void *handle,
const char *matrix);
SPATIALITE_PRIVATE void gaia_do_check_direction (const void *x1,
const void *x2,
char *direction);
SPATIALITE_PRIVATE int gaia_do_check_linestring (const void *geom);
SPATIALITE_PRIVATE void spatialite_internal_init (void *db_handle,
const void *ptr);
SPATIALITE_PRIVATE void spatialite_internal_cleanup (const void *ptr);
SPATIALITE_PRIVATE void gaia_sql_proc_set_error (const void *p_cache,
const char *errmsg);
SPATIALITE_PRIVATE struct gaia_variant_value *gaia_alloc_variant ();
SPATIALITE_PRIVATE void gaia_free_variant (struct gaia_variant_value
*variant);
SPATIALITE_PRIVATE void gaia_set_variant_null (struct gaia_variant_value
*variant);
SPATIALITE_PRIVATE void gaia_set_variant_int64 (struct gaia_variant_value
*variant,
sqlite3_int64 value);
SPATIALITE_PRIVATE void gaia_set_variant_double (struct gaia_variant_value
*variant, double value);
SPATIALITE_PRIVATE int gaia_set_variant_text (struct gaia_variant_value
*variant, const char *value,
int size);
SPATIALITE_PRIVATE int gaia_set_variant_blob (struct gaia_variant_value
*variant,
const unsigned char *value,
int size);
#ifdef _WIN32
SPATIALITE_PRIVATE void splite_pause_windows (void);
#else
SPATIALITE_PRIVATE void splite_pause_signal (void);
#endif
SPATIALITE_PRIVATE void finalize_topologies (const void *p_cache);
SPATIALITE_PRIVATE int create_knn2 (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_data_licenses (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_geometry_columns_time (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_spatial_ref_sys_aux (sqlite3 * handle);
SPATIALITE_PRIVATE int create_raster_coverages (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_vector_coverages (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_wms_tables (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_external_graphics (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_fonts (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_raster_styles (sqlite3 * sqlite, int relaxed);
SPATIALITE_PRIVATE int create_raster_styled_layers (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_vector_styles (sqlite3 * sqlite, int relaxed);
SPATIALITE_PRIVATE int create_vector_styled_layers (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_iso_metadata (sqlite3 * sqlite, int relaxed);
SPATIALITE_PRIVATE int create_iso_metadata_reference (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_iso_metadata_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_rl2map_configurations (sqlite3 * sqlite,
int relaxed);
SPATIALITE_PRIVATE int create_rl2map_configurations_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_external_graphics_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_fonts_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_raster_styled_layers_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_raster_styles_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_vector_styles_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int create_vector_styled_layers_view (sqlite3 * sqlite);
SPATIALITE_PRIVATE int createMissingSystemTables (sqlite3 * sqlite,
const void *cache,
int relaxed,
int transaction,
char **err_msg);
SPATIALITE_PRIVATE int createMissingRasterlite2Columns (sqlite3 *
db_handle);
SPATIALITE_PRIVATE int do_set_multiple_points (sqlite3 * db_handle,
void *line,
sqlite3_int64 pk_value,
const char *table_name,
const char *point_name,
const char *pk_name,
const char *pos_name);
#ifdef __cplusplus
}
#endif
#endif /* _SPATIALITE_PRIVATE_H */
libspatialite-5.1.0/src/headers/Makefile.in 0000644 0001750 0001750 00000046415 14463127014 015547 0000000 0000000 # Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/headers
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__nobase_include_HEADERS_DIST) \
$(am__noinst_HEADERS_DIST) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./fakeconfig.h \
$(top_builddir)/./config.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig.h \
$(top_builddir)/./config-msvc.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig-msvc.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__nobase_include_HEADERS_DIST = spatialite.h spatialite/gaiaconfig.h \
spatialite/gaiaconfig.h.in spatialite/gaiaconfig-msvc.h \
spatialite/gaiaconfig-msvc.h.in spatialite/gaiaexif.h \
spatialite/gaiaaux.h spatialite/gaiamatrix.h \
spatialite/gaiageo.h spatialite/gg_const.h \
spatialite/gg_structs.h spatialite/gg_core.h \
spatialite/gg_mbr.h spatialite/gg_formats.h \
spatialite/gg_dynamic.h spatialite/gg_advanced.h \
spatialite/gg_xml.h spatialite/gg_wfs.h spatialite/gg_dxf.h \
spatialite/spatialite_ext.h spatialite/sqlite.h \
spatialite/debug.h spatialite/geopackage.h \
spatialite/control_points.h spatialite/gaia_topology.h \
spatialite/gaia_network.h spatialite/gg_sequence.h \
spatialite/stored_procedures.h spatialite/geojson.h
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(includedir)"
am__noinst_HEADERS_DIST = spatialite_private.h
HEADERS = $(nobase_include_HEADERS) $(noinst_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GEOSCONFIG = @GEOSCONFIG@
GEOS_CFLAGS = @GEOS_CFLAGS@
GEOS_LDFLAGS = @GEOS_LDFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@MODULE_ONLY_FALSE@noinst_HEADERS = spatialite_private.h
@MODULE_ONLY_TRUE@noinst_HEADERS =
@MODULE_ONLY_FALSE@nobase_include_HEADERS = spatialite.h \
@MODULE_ONLY_FALSE@ spatialite/gaiaconfig.h \
@MODULE_ONLY_FALSE@ spatialite/gaiaconfig.h.in \
@MODULE_ONLY_FALSE@ spatialite/gaiaconfig-msvc.h \
@MODULE_ONLY_FALSE@ spatialite/gaiaconfig-msvc.h.in \
@MODULE_ONLY_FALSE@ spatialite/gaiaexif.h \
@MODULE_ONLY_FALSE@ spatialite/gaiaaux.h \
@MODULE_ONLY_FALSE@ spatialite/gaiamatrix.h \
@MODULE_ONLY_FALSE@ spatialite/gaiageo.h \
@MODULE_ONLY_FALSE@ spatialite/gg_const.h \
@MODULE_ONLY_FALSE@ spatialite/gg_structs.h \
@MODULE_ONLY_FALSE@ spatialite/gg_core.h \
@MODULE_ONLY_FALSE@ spatialite/gg_mbr.h \
@MODULE_ONLY_FALSE@ spatialite/gg_formats.h \
@MODULE_ONLY_FALSE@ spatialite/gg_dynamic.h \
@MODULE_ONLY_FALSE@ spatialite/gg_advanced.h \
@MODULE_ONLY_FALSE@ spatialite/gg_xml.h \
@MODULE_ONLY_FALSE@ spatialite/gg_wfs.h \
@MODULE_ONLY_FALSE@ spatialite/gg_dxf.h \
@MODULE_ONLY_FALSE@ spatialite/spatialite_ext.h \
@MODULE_ONLY_FALSE@ spatialite/sqlite.h \
@MODULE_ONLY_FALSE@ spatialite/debug.h \
@MODULE_ONLY_FALSE@ spatialite/geopackage.h \
@MODULE_ONLY_FALSE@ spatialite/control_points.h \
@MODULE_ONLY_FALSE@ spatialite/gaia_topology.h \
@MODULE_ONLY_FALSE@ spatialite/gaia_network.h \
@MODULE_ONLY_FALSE@ spatialite/gg_sequence.h \
@MODULE_ONLY_FALSE@ spatialite/stored_procedures.h \
@MODULE_ONLY_FALSE@ spatialite/geojson.h
@MODULE_ONLY_TRUE@nobase_include_HEADERS =
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/headers/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/headers/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-nobase_includeHEADERS: $(nobase_include_HEADERS)
@$(NORMAL_INSTALL)
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
done
uninstall-nobase_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-nobase_includeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-nobase_includeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man \
install-nobase_includeHEADERS install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-nobase_includeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
libspatialite-5.1.0/src/versioninfo/ 0000755 0001750 0001750 00000000000 14463127115 014500 5 0000000 0000000 libspatialite-5.1.0/src/versioninfo/version.c 0000644 0001750 0001750 00000004537 14463127014 016260 0000000 0000000 /*
version.c -- Gaia spatial support for SQLite
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
const char spatialiteversion[] = SPATIALITE_VERSION;
#if defined(_WIN32) && !defined(__MINGW32__)
#ifdef _WIN64
const char spatialitetargetcpu[] = "Windows_64bit";
#else
const char spatialitetargetcpu[] = "Windows_32bit";
#endif
#else
const char spatialitetargetcpu[] = SPATIALITE_TARGET_CPU;
#endif
SPATIALITE_DECLARE const char *
spatialite_version (void)
{
return spatialiteversion;
}
SPATIALITE_DECLARE const char *
spatialite_target_cpu (void)
{
return spatialitetargetcpu;
}
libspatialite-5.1.0/src/Makefile.am 0000644 0001750 0001750 00000004711 14463127014 014114 0000000 0000000 AUTOMAKE_OPTIONS = subdir-objects
SUBDIRS = headers \
gaiaaux \
gaiaexif \
gaiageo \
geopackage \
spatialite \
shapefiles \
srsinit \
connection_cache \
virtualtext \
wfs \
dxf \
md5 \
control_points \
cutter \
topology \
stored_procedures
AM_CPPFLAGS = @CFLAGS@ @CPPFLAGS@
AM_CPPFLAGS += -I$(top_srcdir)/src/headers
AM_CPPFLAGS += -I$(top_srcdir)
if MODULE_ONLY
lib_LTLIBRARIES = mod_spatialite.la
else
lib_LTLIBRARIES = libspatialite.la mod_spatialite.la
endif
libspatialite_la_SOURCES = versioninfo/version.c
libspatialite_la_LIBADD = ./gaiaaux/libgaiaaux.la \
./gaiaexif/libgaiaexif.la \
./gaiageo/libgaiageo.la \
./geopackage/libgeopackage.la \
./spatialite/libsplite.la \
./shapefiles/libshapefiles.la \
./dxf/libdxf.la \
./md5/libmd5.la \
./control_points/libcontrol_points.la \
./cutter/libcutter.la \
./topology/libtopology.la \
./srsinit/libsrsinit.la \
./stored_procedures/libstored_procedures.la \
./connection_cache/libconnection_cache.la \
./virtualtext/libvirtualtext.la \
./wfs/libwfs.la @LIBXML2_LIBS@ @SQLITE3_LIBS@
if MINGW
libspatialite_la_LDFLAGS = -version-info 5:1:0 -no-undefined
libspatialite_la_LIBADD += -lm
else
if ANDROID
libspatialite_la_LDFLAGS = -version-info 9:0:1
libspatialite_la_LIBADD += -ldl -lm
else
libspatialite_la_LDFLAGS = -version-info 9:0:1
libspatialite_la_LIBADD += -lpthread -ldl -lm
endif
endif
mod_spatialite_la_SOURCES = versioninfo/version.c
mod_spatialite_la_LIBADD = ./gaiaaux/gaiaaux.la \
./gaiaexif/gaiaexif.la \
./gaiageo/gaiageo.la \
./geopackage/geopackage.la \
./spatialite/splite.la \
./shapefiles/shapefiles.la \
./dxf/dxf.la \
./md5/md5.la \
./control_points/control_points.la \
./cutter/cutter.la \
./topology/topology.la \
./srsinit/srsinit.la \
./stored_procedures/stored_procedures.la \
./connection_cache/connection_cache.la \
./virtualtext/virtualtext.la \
./wfs/wfs.la @LIBXML2_LIBS@
mod_spatialite_la_CPPFLAGS = @CFLAGS@ @CPPFLAGS@
mod_spatialite_la_CPPFLAGS += -I$(top_srcdir)/src/headers -I.
mod_spatialite_la_CPPFLAGS += -DLOADABLE_EXTENSION
mod_spatialite_la_LIBTOOLFLAGS = --tag=disable-static
if MINGW
mod_spatialite_la_LDFLAGS = -module -avoid-version -no-undefined
mod_spatialite_la_LIBADD += -lm
else
if ANDROID
mod_spatialite_la_LDFLAGS = -module -version-info 9:0:1
mod_spatialite_la_LIBADD += -ldl -lm
else
mod_spatialite_la_LDFLAGS = -module -version-info 9:0:1
mod_spatialite_la_LIBADD += -lpthread -ldl -lm
endif
endif
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
libspatialite-5.1.0/src/Makefile.in 0000644 0001750 0001750 00000077356 14463127014 014144 0000000 0000000 # Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@MINGW_TRUE@am__append_1 = -lm
@ANDROID_TRUE@@MINGW_FALSE@am__append_2 = -ldl -lm
@ANDROID_FALSE@@MINGW_FALSE@am__append_3 = -lpthread -ldl -lm
@MINGW_TRUE@am__append_4 = -lm
@ANDROID_TRUE@@MINGW_FALSE@am__append_5 = -ldl -lm
@ANDROID_FALSE@@MINGW_FALSE@am__append_6 = -lpthread -ldl -lm
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./fakeconfig.h \
$(top_builddir)/./config.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig.h \
$(top_builddir)/./config-msvc.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig-msvc.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libspatialite_la_DEPENDENCIES = ./gaiaaux/libgaiaaux.la \
./gaiaexif/libgaiaexif.la ./gaiageo/libgaiageo.la \
./geopackage/libgeopackage.la ./spatialite/libsplite.la \
./shapefiles/libshapefiles.la ./dxf/libdxf.la ./md5/libmd5.la \
./control_points/libcontrol_points.la ./cutter/libcutter.la \
./topology/libtopology.la ./srsinit/libsrsinit.la \
./stored_procedures/libstored_procedures.la \
./connection_cache/libconnection_cache.la \
./virtualtext/libvirtualtext.la ./wfs/libwfs.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am__dirstamp = $(am__leading_dot)dirstamp
am_libspatialite_la_OBJECTS = versioninfo/version.lo
libspatialite_la_OBJECTS = $(am_libspatialite_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libspatialite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libspatialite_la_LDFLAGS) $(LDFLAGS) \
-o $@
@MODULE_ONLY_FALSE@am_libspatialite_la_rpath = -rpath $(libdir)
mod_spatialite_la_DEPENDENCIES = ./gaiaaux/gaiaaux.la \
./gaiaexif/gaiaexif.la ./gaiageo/gaiageo.la \
./geopackage/geopackage.la ./spatialite/splite.la \
./shapefiles/shapefiles.la ./dxf/dxf.la ./md5/md5.la \
./control_points/control_points.la ./cutter/cutter.la \
./topology/topology.la ./srsinit/srsinit.la \
./stored_procedures/stored_procedures.la \
./connection_cache/connection_cache.la \
./virtualtext/virtualtext.la ./wfs/wfs.la \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am_mod_spatialite_la_OBJECTS = \
versioninfo/mod_spatialite_la-version.lo
mod_spatialite_la_OBJECTS = $(am_mod_spatialite_la_OBJECTS)
mod_spatialite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(mod_spatialite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(mod_spatialite_la_LDFLAGS) \
$(LDFLAGS) -o $@
@MODULE_ONLY_FALSE@am_mod_spatialite_la_rpath = -rpath $(libdir)
@MODULE_ONLY_TRUE@am_mod_spatialite_la_rpath = -rpath $(libdir)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/. -I$(top_builddir)/./src/headers/spatialite
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = \
versioninfo/$(DEPDIR)/mod_spatialite_la-version.Plo \
versioninfo/$(DEPDIR)/version.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libspatialite_la_SOURCES) $(mod_spatialite_la_SOURCES)
DIST_SOURCES = $(libspatialite_la_SOURCES) \
$(mod_spatialite_la_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir distdir-am
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GEOSCONFIG = @GEOSCONFIG@
GEOS_CFLAGS = @GEOS_CFLAGS@
GEOS_LDFLAGS = @GEOS_LDFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects
SUBDIRS = headers \
gaiaaux \
gaiaexif \
gaiageo \
geopackage \
spatialite \
shapefiles \
srsinit \
connection_cache \
virtualtext \
wfs \
dxf \
md5 \
control_points \
cutter \
topology \
stored_procedures
AM_CPPFLAGS = @CFLAGS@ @CPPFLAGS@ -I$(top_srcdir)/src/headers \
-I$(top_srcdir)
@MODULE_ONLY_FALSE@lib_LTLIBRARIES = libspatialite.la mod_spatialite.la
@MODULE_ONLY_TRUE@lib_LTLIBRARIES = mod_spatialite.la
libspatialite_la_SOURCES = versioninfo/version.c
libspatialite_la_LIBADD = ./gaiaaux/libgaiaaux.la \
./gaiaexif/libgaiaexif.la ./gaiageo/libgaiageo.la \
./geopackage/libgeopackage.la ./spatialite/libsplite.la \
./shapefiles/libshapefiles.la ./dxf/libdxf.la ./md5/libmd5.la \
./control_points/libcontrol_points.la ./cutter/libcutter.la \
./topology/libtopology.la ./srsinit/libsrsinit.la \
./stored_procedures/libstored_procedures.la \
./connection_cache/libconnection_cache.la \
./virtualtext/libvirtualtext.la ./wfs/libwfs.la @LIBXML2_LIBS@ \
@SQLITE3_LIBS@ $(am__append_1) $(am__append_2) $(am__append_3)
@ANDROID_FALSE@@MINGW_FALSE@libspatialite_la_LDFLAGS = -version-info 9:0:1
@ANDROID_TRUE@@MINGW_FALSE@libspatialite_la_LDFLAGS = -version-info 9:0:1
@MINGW_TRUE@libspatialite_la_LDFLAGS = -version-info 5:1:0 -no-undefined
mod_spatialite_la_SOURCES = versioninfo/version.c
mod_spatialite_la_LIBADD = ./gaiaaux/gaiaaux.la ./gaiaexif/gaiaexif.la \
./gaiageo/gaiageo.la ./geopackage/geopackage.la \
./spatialite/splite.la ./shapefiles/shapefiles.la ./dxf/dxf.la \
./md5/md5.la ./control_points/control_points.la \
./cutter/cutter.la ./topology/topology.la ./srsinit/srsinit.la \
./stored_procedures/stored_procedures.la \
./connection_cache/connection_cache.la \
./virtualtext/virtualtext.la ./wfs/wfs.la @LIBXML2_LIBS@ \
$(am__append_4) $(am__append_5) $(am__append_6)
mod_spatialite_la_CPPFLAGS = @CFLAGS@ @CPPFLAGS@ \
-I$(top_srcdir)/src/headers -I. -DLOADABLE_EXTENSION
mod_spatialite_la_LIBTOOLFLAGS = --tag=disable-static
@ANDROID_FALSE@@MINGW_FALSE@mod_spatialite_la_LDFLAGS = -module -version-info 9:0:1
@ANDROID_TRUE@@MINGW_FALSE@mod_spatialite_la_LDFLAGS = -module -version-info 9:0:1
@MINGW_TRUE@mod_spatialite_la_LDFLAGS = -module -avoid-version -no-undefined
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
versioninfo/$(am__dirstamp):
@$(MKDIR_P) versioninfo
@: > versioninfo/$(am__dirstamp)
versioninfo/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) versioninfo/$(DEPDIR)
@: > versioninfo/$(DEPDIR)/$(am__dirstamp)
versioninfo/version.lo: versioninfo/$(am__dirstamp) \
versioninfo/$(DEPDIR)/$(am__dirstamp)
libspatialite.la: $(libspatialite_la_OBJECTS) $(libspatialite_la_DEPENDENCIES) $(EXTRA_libspatialite_la_DEPENDENCIES)
$(AM_V_CCLD)$(libspatialite_la_LINK) $(am_libspatialite_la_rpath) $(libspatialite_la_OBJECTS) $(libspatialite_la_LIBADD) $(LIBS)
versioninfo/mod_spatialite_la-version.lo: versioninfo/$(am__dirstamp) \
versioninfo/$(DEPDIR)/$(am__dirstamp)
mod_spatialite.la: $(mod_spatialite_la_OBJECTS) $(mod_spatialite_la_DEPENDENCIES) $(EXTRA_mod_spatialite_la_DEPENDENCIES)
$(AM_V_CCLD)$(mod_spatialite_la_LINK) $(am_mod_spatialite_la_rpath) $(mod_spatialite_la_OBJECTS) $(mod_spatialite_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f versioninfo/*.$(OBJEXT)
-rm -f versioninfo/*.lo
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@versioninfo/$(DEPDIR)/mod_spatialite_la-version.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@versioninfo/$(DEPDIR)/version.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
versioninfo/mod_spatialite_la-version.lo: versioninfo/version.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_spatialite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_spatialite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT versioninfo/mod_spatialite_la-version.lo -MD -MP -MF versioninfo/$(DEPDIR)/mod_spatialite_la-version.Tpo -c -o versioninfo/mod_spatialite_la-version.lo `test -f 'versioninfo/version.c' || echo '$(srcdir)/'`versioninfo/version.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) versioninfo/$(DEPDIR)/mod_spatialite_la-version.Tpo versioninfo/$(DEPDIR)/mod_spatialite_la-version.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='versioninfo/version.c' object='versioninfo/mod_spatialite_la-version.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_spatialite_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_spatialite_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o versioninfo/mod_spatialite_la-version.lo `test -f 'versioninfo/version.c' || echo '$(srcdir)/'`versioninfo/version.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-rm -rf versioninfo/.libs versioninfo/_libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f versioninfo/$(DEPDIR)/$(am__dirstamp)
-rm -f versioninfo/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
-rm -f versioninfo/$(DEPDIR)/mod_spatialite_la-version.Plo
-rm -f versioninfo/$(DEPDIR)/version.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f versioninfo/$(DEPDIR)/mod_spatialite_la-version.Plo
-rm -f versioninfo/$(DEPDIR)/version.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--depfiles check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-libLTLIBRARIES
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
libspatialite-5.1.0/src/gaiaaux/ 0000755 0001750 0001750 00000000000 14463127115 013556 5 0000000 0000000 libspatialite-5.1.0/src/gaiaaux/Makefile.am 0000644 0001750 0001750 00000001023 14463127014 015524 0000000 0000000
AM_CPPFLAGS = -I$(top_srcdir)/src/headers
AM_CPPFLAGS += @CFLAGS@ @CPPFLAGS@
noinst_LTLIBRARIES = libgaiaaux.la gaiaaux.la
GAIAAUX_COMMON_SOURCES = gg_sqlaux.c gg_utf8.c
libgaiaaux_la_SOURCES = $(GAIAAUX_COMMON_SOURCES)
gaiaaux_la_SOURCES = $(GAIAAUX_COMMON_SOURCES)
gaiaaux_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I.
gaiaaux_la_CPPFLAGS += @CFLAGS@ @CPPFLAGS@
gaiaaux_la_CPPFLAGS += -DLOADABLE_EXTENSION
gaiaaux_la_LDFLAGS = -module
gaiaaux_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
libspatialite-5.1.0/src/gaiaaux/Makefile.in 0000644 0001750 0001750 00000053530 14463127014 015547 0000000 0000000 # Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/gaiaaux
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./fakeconfig.h \
$(top_builddir)/./config.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig.h \
$(top_builddir)/./config-msvc.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig-msvc.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
gaiaaux_la_LIBADD =
am__objects_1 = gaiaaux_la-gg_sqlaux.lo gaiaaux_la-gg_utf8.lo
am_gaiaaux_la_OBJECTS = $(am__objects_1)
gaiaaux_la_OBJECTS = $(am_gaiaaux_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
gaiaaux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(gaiaaux_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(gaiaaux_la_LDFLAGS) $(LDFLAGS) -o $@
libgaiaaux_la_LIBADD =
am__objects_2 = gg_sqlaux.lo gg_utf8.lo
am_libgaiaaux_la_OBJECTS = $(am__objects_2)
libgaiaaux_la_OBJECTS = $(am_libgaiaaux_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/. -I$(top_builddir)/./src/headers/spatialite
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/gaiaaux_la-gg_sqlaux.Plo \
./$(DEPDIR)/gaiaaux_la-gg_utf8.Plo ./$(DEPDIR)/gg_sqlaux.Plo \
./$(DEPDIR)/gg_utf8.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(gaiaaux_la_SOURCES) $(libgaiaaux_la_SOURCES)
DIST_SOURCES = $(gaiaaux_la_SOURCES) $(libgaiaaux_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GEOSCONFIG = @GEOSCONFIG@
GEOS_CFLAGS = @GEOS_CFLAGS@
GEOS_LDFLAGS = @GEOS_LDFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/src/headers @CFLAGS@ @CPPFLAGS@
noinst_LTLIBRARIES = libgaiaaux.la gaiaaux.la
GAIAAUX_COMMON_SOURCES = gg_sqlaux.c gg_utf8.c
libgaiaaux_la_SOURCES = $(GAIAAUX_COMMON_SOURCES)
gaiaaux_la_SOURCES = $(GAIAAUX_COMMON_SOURCES)
gaiaaux_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I. @CFLAGS@ \
@CPPFLAGS@ -DLOADABLE_EXTENSION
gaiaaux_la_LDFLAGS = -module
gaiaaux_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/gaiaaux/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/gaiaaux/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
gaiaaux.la: $(gaiaaux_la_OBJECTS) $(gaiaaux_la_DEPENDENCIES) $(EXTRA_gaiaaux_la_DEPENDENCIES)
$(AM_V_CCLD)$(gaiaaux_la_LINK) $(gaiaaux_la_OBJECTS) $(gaiaaux_la_LIBADD) $(LIBS)
libgaiaaux.la: $(libgaiaaux_la_OBJECTS) $(libgaiaaux_la_DEPENDENCIES) $(EXTRA_libgaiaaux_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libgaiaaux_la_OBJECTS) $(libgaiaaux_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiaaux_la-gg_sqlaux.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiaaux_la-gg_utf8.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_sqlaux.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_utf8.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
gaiaaux_la-gg_sqlaux.lo: gg_sqlaux.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaaux_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaaux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiaaux_la-gg_sqlaux.lo -MD -MP -MF $(DEPDIR)/gaiaaux_la-gg_sqlaux.Tpo -c -o gaiaaux_la-gg_sqlaux.lo `test -f 'gg_sqlaux.c' || echo '$(srcdir)/'`gg_sqlaux.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiaaux_la-gg_sqlaux.Tpo $(DEPDIR)/gaiaaux_la-gg_sqlaux.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_sqlaux.c' object='gaiaaux_la-gg_sqlaux.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaaux_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaaux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiaaux_la-gg_sqlaux.lo `test -f 'gg_sqlaux.c' || echo '$(srcdir)/'`gg_sqlaux.c
gaiaaux_la-gg_utf8.lo: gg_utf8.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaaux_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaaux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiaaux_la-gg_utf8.lo -MD -MP -MF $(DEPDIR)/gaiaaux_la-gg_utf8.Tpo -c -o gaiaaux_la-gg_utf8.lo `test -f 'gg_utf8.c' || echo '$(srcdir)/'`gg_utf8.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiaaux_la-gg_utf8.Tpo $(DEPDIR)/gaiaaux_la-gg_utf8.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_utf8.c' object='gaiaaux_la-gg_utf8.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaaux_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaaux_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiaaux_la-gg_utf8.lo `test -f 'gg_utf8.c' || echo '$(srcdir)/'`gg_utf8.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/gaiaaux_la-gg_sqlaux.Plo
-rm -f ./$(DEPDIR)/gaiaaux_la-gg_utf8.Plo
-rm -f ./$(DEPDIR)/gg_sqlaux.Plo
-rm -f ./$(DEPDIR)/gg_utf8.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gaiaaux_la-gg_sqlaux.Plo
-rm -f ./$(DEPDIR)/gaiaaux_la-gg_utf8.Plo
-rm -f ./$(DEPDIR)/gg_sqlaux.Plo
-rm -f ./$(DEPDIR)/gg_utf8.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
libspatialite-5.1.0/src/gaiaaux/gg_sqlaux.c 0000644 0001750 0001750 00000066134 14463127014 015644 0000000 0000000 /*
gg_sqlaux.c -- SQL ancillary functions
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
-----------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#ifdef _WIN32
#define strcasecmp _stricmp
#endif /* not WIN32 */
/* 64 bit integer: portable format for printf() */
#if defined(_WIN32) && !defined(__MINGW32__)
#define FRMT64 "%I64d"
#else
#define FRMT64 "%lld"
#endif
GAIAAUX_DECLARE int
gaiaIllegalSqlName (const char *name)
{
/* checks if column-name is an SQL illegal name */
int i;
int len;
if (!name)
return 1;
len = strlen (name);
if (len == 0)
return 1;
for (i = 0; i < len; i++)
{
if (name[i] >= 'a' && name[i] <= 'z')
continue;
if (name[i] >= 'A' && name[i] <= 'Z')
continue;
if (name[i] >= '0' && name[i] <= '9')
continue;
if (name[i] == '_')
continue;
/* the name contains an illegal char */
return 1;
}
if (name[0] >= 'a' && name[0] <= 'z')
return 0;
if (name[0] >= 'A' && name[0] <= 'Z')
return 0;
/* the first char in the name isn't a letter */
return 1;
}
GAIAAUX_DECLARE int
gaiaIsReservedSqliteName (const char *name)
{
/* checks if column-name is an SQLite reserved keyword */
char *reserved[] = {
"ALL",
"ALTER",
"AND",
"AS",
"AUTOINCREMENT",
"BETWEEN",
"BLOB",
"BY",
"CASE",
"CHECK",
"COLLATE",
"COMMIT",
"CONSTRAINT",
"CREATE",
"CROSS",
"DATE",
"DATETIME",
"DEFAULT",
"DEFERRABLE",
"DELETE",
"DISTINCT",
"DOUBLE",
"DROP",
"ELSE",
"ESCAPE",
"EXCEPT",
"FOREIGN",
"FROM",
"FULL",
"GLOB",
"GROUP",
"HAVING",
"IN",
"INDEX",
"INNER",
"INSERT",
"INTEGER",
"INTERSECT",
"INTO",
"IS",
"ISNULL",
"JOIN",
"KEY",
"LEFT",
"LIKE",
"LIMIT",
"MATCH",
"NATURAL",
"NOT",
"NOTNULL",
"NULL",
"ON",
"OR",
"ORDER",
"OUTER",
"PRAGMA",
"PRIMARY",
"REFERENCES",
"REPLACE",
"RIGHT",
"ROLLBACK",
"SELECT",
"SET",
"TABLE",
"TEMP",
"TEMPORARY",
"THEN",
"TEXT",
"TIMESTAMP",
"TO",
"TRANSACTION",
"UNION",
"UNIQUE",
"UPDATE",
"USING",
"VALUES",
"VIEW",
"WHEN",
"WHERE",
NULL
};
char **pw = reserved;
while (*pw != NULL)
{
if (strcasecmp (name, *pw) == 0)
return 1;
pw++;
}
return 0;
}
GAIAAUX_DECLARE int
gaiaIsReservedSqlName (const char *name)
{
/* checks if column-name is an SQL reserved keyword */
char *reserved[] = {
"ABSOLUTE",
"ACTION",
"ADD",
"AFTER",
"ALL",
"ALLOCATE",
"ALTER",
"AND",
"ANY",
"ARE",
"ARRAY",
"AS",
"ASC",
"ASENSITIVE",
"ASSERTION",
"ASYMMETRIC",
"AT",
"ATOMIC",
"AUTHORIZATION",
"AVG",
"BEFORE",
"BEGIN",
"BETWEEN",
"BIGINT",
"BINARY",
"BIT",
"BIT_LENGTH",
"BLOB",
"BOOLEAN",
"BOTH",
"BREADTH",
"BY",
"CALL",
"CALLED",
"CASCADE",
"CASCADED",
"CASE",
"CAST",
"CATALOG",
"CHAR",
"CHARACTER",
"CHARACTER_LENGTH",
"CHAR_LENGTH",
"CHECK",
"CLOB",
"CLOSE",
"COALESCE",
"COLLATE",
"COLLATION",
"COLUMN",
"COMMIT",
"CONDITION",
"CONNECT",
"CONNECTION",
"CONSTRAINT",
"CONSTRAINTS",
"CONSTRUCTOR",
"CONTAINS",
"CONTINUE",
"CONVERT",
"CORRESPONDING",
"COUNT",
"CREATE",
"CROSS",
"CUBE",
"CURRENT",
"CURRENT_DATE",
"CURRENT_DEFAULT_TRANSFORM_GROUP",
"CURRENT_PATH",
"CURRENT_ROLE",
"CURRENT_TIME",
"CURRENT_TIMESTAMP",
"CURRENT_TRANSFORM_GROUP_FOR_TYPE",
"CURRENT_USER",
"CURSOR",
"CYCLE",
"DATA",
"DATE",
"DAY",
"DEALLOCATE",
"DEC",
"DECIMAL",
"DECLARE",
"DEFAULT",
"DEFERRABLE",
"DEFERRED",
"DELETE",
"DEPTH",
"DEREF",
"DESC",
"DESCRIBE",
"DESCRIPTOR",
"DETERMINISTIC",
"DIAGNOSTICS",
"DISCONNECT",
"DISTINCT",
"DO",
"DOMAIN",
"DOUBLE",
"DROP",
"DYNAMIC",
"EACH",
"ELEMENT",
"ELSE",
"ELSEIF",
"END",
"EQUALS",
"ESCAPE",
"EXCEPT",
"EXCEPTION",
"EXEC",
"EXECUTE",
"EXISTS",
"EXIT",
"external",
"EXTRACT",
"FALSE",
"FETCH",
"FILTER",
"FIRST",
"FLOAT",
"FOR",
"FOREIGN",
"FOUND",
"FREE",
"FROM",
"FULL",
"FUNCTION",
"GENERAL",
"GET",
"GLOBAL",
"GO",
"GOTO",
"GRANT",
"GROUP",
"GROUPING",
"HANDLER",
"HAVING",
"HOLD",
"HOUR",
"IDENTITY",
"IF",
"IMMEDIATE",
"IN",
"INDICATOR",
"INITIALLY",
"INNER",
"INOUT",
"INPUT",
"INSENSITIVE",
"INSERT",
"INT",
"INTEGER",
"INTERSECT",
"INTERVAL",
"INTO",
"IS",
"ISOLATION",
"ITERATE",
"JOIN",
"KEY",
"LANGUAGE",
"LARGE",
"LAST",
"LATERAL",
"LEADING",
"LEAVE",
"LEFT",
"LEVEL",
"LIKE",
"LOCAL",
"LOCALTIME",
"LOCALTIMESTAMP",
"LOCATOR",
"LOOP",
"LOWER",
"MAP",
"MATCH",
"MAX",
"MEMBER",
"MERGE",
"METHOD",
"MIN",
"MINUTE",
"MODIFIES",
"MODULE",
"MONTH",
"MULTISET",
"NAMES",
"NATIONAL",
"NATURAL",
"NCHAR",
"NCLOB",
"NEW",
"NEXT",
"NO",
"NONE",
"NOT",
"NULL",
"NULLIF",
"NUMERIC",
"OBJECT",
"OCTET_LENGTH",
"OF",
"OLD",
"ON",
"ONLY",
"OPEN",
"OPTION",
"OR",
"ORDER",
"ORDINALITY",
"OUT",
"OUTER",
"OUTPUT",
"OVER",
"OVERLAPS",
"PAD",
"PARAMETER",
"PARTIAL",
"PARTITION",
"PATH",
"POSITION",
"PRECISION",
"PREPARE",
"PRESERVE",
"PRIMARY",
"PRIOR",
"PRIVILEGES",
"PROCEDURE",
"PUBLIC",
"RANGE",
"READ",
"READS",
"REAL",
"RECURSIVE",
"REF",
"REFERENCES",
"REFERENCING",
"RELATIVE",
"RELEASE",
"REPEAT",
"RESIGNAL",
"RESTRICT",
"RESULT",
"RETURN",
"RETURNS",
"REVOKE",
"RIGHT",
"ROLE",
"ROLLBACK",
"ROLLUP",
"ROUTINE",
"ROW",
"ROWS",
"SAVEPOINT",
"SCHEMA",
"SCOPE",
"SCROLL",
"SEARCH",
"SECOND",
"SECTION",
"SELECT",
"SENSITIVE",
"SESSION",
"SESSION_USER",
"SET",
"SETS",
"SIGNAL",
"SIMILAR",
"SIZE",
"SMALLINT",
"SOME",
"SPACE",
"SPECIFIC",
"SPECIFICTYPE",
"SQL",
"SQLCODE",
"SQLERROR",
"SQLEXCEPTION",
"SQLSTATE",
"SQLWARNING",
"START",
"STATE",
"STATIC",
"SUBMULTISET",
"SUBSTRING",
"SUM",
"SYMMETRIC",
"SYSTEM",
"SYSTEM_USER",
"TABLE",
"TABLESAMPLE",
"TEMPORARY",
"THEN",
"TIME",
"TIMESTAMP",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
"TO",
"TRAILING",
"TRANSACTION",
"TRANSLATE",
"TRANSLATION",
"TREAT",
"TRIGGER",
"TRIM",
"TRUE",
"UNDER",
"UNDO",
"UNION",
"UNIQUE",
"UNKNOWN",
"UNNEST",
"UNTIL",
"UPDATE",
"UPPER",
"USAGE",
"USER",
"USING",
"VALUE",
"VALUES",
"VARCHAR",
"VARYING",
"VIEW",
"WHEN",
"WHENEVER",
"WHERE",
"WHILE",
"WINDOW",
"WITH",
"WITHIN",
"WITHOUT",
"WORK",
"WRITE",
"YEAR",
"ZONE",
NULL
};
char **pw = reserved;
while (*pw != NULL)
{
if (strcasecmp (name, *pw) == 0)
return 1;
pw++;
}
return 0;
}
GAIAAUX_DECLARE char *
gaiaDequotedSql (const char *value)
{
/*
/ returns a well formatted TEXT value from SQL
/ 1] if the input string begins and ends with ' sigle quote will be the target
/ 2] if the input string begins and ends with " double quote will be the target
/ 3] in any othet case the string will simply be copied
*/
const char *pi = value;
const char *start;
const char *end;
char *clean;
char *po;
int len;
char target;
int mark = 0;
if (value == NULL)
return NULL;
len = strlen (value);
clean = malloc (len + 1);
if (*(value + 0) == '"' && *(value + len - 1) == '"')
target = '"';
else if (*(value + 0) == '\'' && *(value + len - 1) == '\'')
target = '\'';
else
{
/* no dequoting; simply copying */
strcpy (clean, value);
return clean;
}
start = value;
end = value + len - 1;
po = clean;
while (*pi != '\0')
{
if (mark)
{
if (*pi == target)
{
*po++ = *pi++;
mark = 0;
continue;
}
else
{
/* error: mismatching quote */
free (clean);
return NULL;
}
}
if (*pi == target)
{
if (pi == start || pi == end)
{
/* first or last char */
pi++;
continue;
}
/* found a quote marker */
mark = 1;
pi++;
continue;
}
*po++ = *pi++;
}
*po = '\0';
return clean;
}
GAIAAUX_DECLARE char *
gaiaQuotedSql (const char *value, int quote)
{
/*
/ returns a well formatted TEXT value for SQL
/ 1] strips trailing spaces
/ 2] masks any QUOTE inside the string, appending another QUOTE
/ 3] works for both SINGLE- and DOUBLE-QUOTE
*/
const char *p_in;
const char *p_end;
char qt;
char *out;
char *p_out;
int len = 0;
int i;
if (!value)
return NULL;
if (quote == GAIA_SQL_SINGLE_QUOTE)
qt = '\'';
else if (quote == GAIA_SQL_DOUBLE_QUOTE)
qt = '"';
else
return NULL;
p_end = value;
for (i = (strlen (value) - 1); i >= 0; i--)
{
/* stripping trailing spaces */
p_end = value + i;
if (value[i] != ' ')
break;
}
p_in = value;
while (p_in <= p_end)
{
/* computing the output length */
len++;
if (*p_in == qt)
len++;
p_in++;
}
if (len == 1 && *value == ' ')
{
/* empty string */
len = 0;
}
out = malloc (len + 1);
if (!out)
return NULL;
if (len == 0)
{
/* empty string */
*out = '\0';
return out;
}
p_out = out;
p_in = value;
while (p_in <= p_end)
{
/* creating the output string */
if (*p_in == qt)
*p_out++ = qt;
*p_out++ = *p_in++;
}
*p_out = '\0';
return out;
}
GAIAAUX_DECLARE char *
gaiaSingleQuotedSql (const char *value)
{
/* convenience method supporting SINGLE-QUOTES */
return gaiaQuotedSql (value, GAIA_SQL_SINGLE_QUOTE);
}
GAIAAUX_DECLARE char *
gaiaDoubleQuotedSql (const char *value)
{
/* convenience method supporting DOUBLE-QUOTES */
return gaiaQuotedSql (value, GAIA_SQL_DOUBLE_QUOTE);
}
GAIAAUX_DECLARE void
gaiaCleanSqlString (char *value)
{
/*
/ returns a well formatted TEXT value for SQL
/ 1] strips trailing spaces
/ 2] masks any ' inside the string, appending another '
*/
char new_value[1024];
char *p;
int len;
int i;
len = strlen (value);
for (i = (len - 1); i >= 0; i--)
{
/* stripping trailing spaces */
if (value[i] == ' ')
value[i] = '\0';
else
break;
}
p = new_value;
for (i = 0; i < len; i++)
{
if (value[i] == '\'')
*(p++) = '\'';
*(p++) = value[i];
}
*p = '\0';
strcpy (value, new_value);
}
GAIAAUX_DECLARE void
gaiaInsertIntoSqlLog (sqlite3 * sqlite, const char *user_agent,
const char *utf8Sql, sqlite3_int64 * sqllog_pk)
{
/* inserting an event into the SQL Log */
char *sql_statement;
int ret;
*sqllog_pk = -1;
if (checkSpatialMetaData (sqlite) != 3)
{
/* CURRENT db-schema (>= 4.0.0) required */
return;
}
sql_statement = sqlite3_mprintf ("INSERT INTO sql_statements_log "
"(id, time_start, user_agent, sql_statement) VALUES ("
"NULL, strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now'), %Q, %Q)",
user_agent, utf8Sql);
ret = sqlite3_exec (sqlite, sql_statement, NULL, 0, NULL);
sqlite3_free (sql_statement);
if (ret != SQLITE_OK)
return;
*sqllog_pk = sqlite3_last_insert_rowid (sqlite);
}
GAIAAUX_DECLARE void
gaiaUpdateSqlLog (sqlite3 * sqlite, sqlite3_int64 sqllog_pk, int success,
const char *errMsg)
{
/* completing an event already inserted into the SQL Log */
char *sql_statement;
char dummy[64];
if (checkSpatialMetaData (sqlite) != 3)
{
/* CURRENT db-schema (>= 4.0.0) required */
return;
}
sprintf (dummy, FRMT64, sqllog_pk);
if (success)
{
sql_statement = sqlite3_mprintf ("UPDATE sql_statements_log SET "
"time_end = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now'), "
"success = 1, error_cause = 'success' WHERE id = %s",
dummy);
}
else
{
sql_statement = sqlite3_mprintf ("UPDATE sql_statements_log SET "
"time_end = strftime('%%Y-%%m-%%dT%%H:%%M:%%fZ', 'now'), "
"success = 0, error_cause = %Q WHERE id = %s",
(errMsg == NULL)
? "UNKNOWN" : errMsg, dummy);
}
sqlite3_exec (sqlite, sql_statement, NULL, 0, NULL);
sqlite3_free (sql_statement);
}
static void
consume_blank (const char *p_start, const char **p_end)
{
/* consuming blanks */
const char *p = p_start;
while (1)
{
if (*p == ' ' || *p == '\t')
{
p++;
continue;
}
else
{
*p_end = p;
return;
}
}
}
static int
check_deg_delimiter (const char *p_start, const char **p_end)
{
/* testing a "degrees" delimiter/qualifier */
unsigned char ctrl1;
unsigned char ctrl2;
if (*p_start == 'd')
{
*p_end = p_start + 1;
return 1;
}
ctrl1 = *(p_start + 0);
ctrl2 = *(p_start + 1);
if (ctrl1 == 0xc2 && ctrl2 == 0xb0)
{
*p_end = p_start + 2;
return 1;
}
return 0;
}
static int
check_min_delimiter (const char *p_start, const char **p_end)
{
/* testing a "minutes" delimiter/qualifier */
unsigned char ctrl1;
unsigned char ctrl2;
unsigned char ctrl3;
if (*p_start == '\'')
{
*p_end = p_start + 1;
return 1;
}
ctrl1 = *(p_start + 0);
ctrl2 = *(p_start + 1);
ctrl3 = *(p_start + 2);
if (ctrl1 == 0xe2 && ctrl2 == 0x80 && ctrl3 == 0xb2)
{
*p_end = p_start + 3;
return 1;
}
return 0;
}
static int
check_sec_delimiter (const char *p_start, const char **p_end)
{
/* testing a "seconds" delimiter/qualifier */
unsigned char ctrl1;
unsigned char ctrl2;
unsigned char ctrl3;
if (*p_start == '"')
{
*p_end = p_start + 1;
return 1;
}
ctrl1 = *(p_start + 0);
ctrl2 = *(p_start + 1);
ctrl3 = *(p_start + 2);
if (ctrl1 == 0xe2 && ctrl2 == 0x80 && ctrl3 == 0xb3)
{
*p_end = p_start + 3;
return 1;
}
return 0;
}
static void
consume_int (const char *p_start, const char **p_end, int *value)
{
/* consuming an integer value */
char *buf;
int len = 0;
const char *p = p_start;
while (1)
{
if (*p >= '0' && *p <= '9')
{
len++;
p++;
continue;
}
else
{
*p_end = p;
break;
}
}
if (len == 0)
{
*value = 181;
return;
}
buf = malloc (len + 1);
memcpy (buf, p_start, len);
*(buf + len) = '\0';
*value = atoi (buf);
free (buf);
}
static void
consume_float (const char *p_start, const char **p_end, double *value)
{
/* consuming a double value */
char *buf;
int pt = 0;
int len = 0;
const char *p = p_start;
while (1)
{
if (*p >= '0' && *p <= '9')
{
len++;
p++;
continue;
}
else if (*p == '.' || *p == ',')
{
len++;
pt++;
p++;
continue;
}
else
{
*p_end = p;
break;
}
}
if (len == 0 || pt > 1)
{
*value = 61.0;
return;
}
buf = malloc (len + 1);
memcpy (buf, p_start, len);
*(buf + len) = '\0';
*value = atof (buf);
free (buf);
}
GAIAAUX_DECLARE int
gaiaParseDMS (const char *dms, double *longitude, double *latitude)
{
/* attempting to parse a DMS string */
double lg;
double lt;
int lat_d;
int lat_m;
double lat_s;
char lat_prefix = '\0';
int long_d;
int long_m;
double long_s;
char long_prefix = '\0';
const char *p = dms;
const char *p_end;
if (dms == NULL)
return 0;
/* attempting to parse the latitude */
consume_blank (p, &p_end);
p = p_end;
if (*p == 'S' || *p == 'N')
{
lat_prefix = *p;
p++;
consume_blank (p, &p_end);
p = p_end;
}
if (*p >= '0' && *p <= '9')
{
consume_int (p, &p_end, &lat_d);
if (lat_d < 0 || lat_d > 90)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_deg_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (*p >= '0' && *p <= '9')
{
consume_int (p, &p_end, &lat_m);
if (lat_m < 0 || lat_m >= 60)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_min_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (*p >= '0' && *p <= '9')
{
consume_float (p, &p_end, &lat_s);
if (lat_s < 0.0 || lat_s >= 60.0)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_sec_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (lat_prefix == '\0')
{
/* attempting to retrieve the prefix */
if (*p == 'S' || *p == 'N')
{
lat_prefix = *p;
p++;
}
else
return 0;
}
lt = (double) lat_d + ((double) lat_m / 60.0) + (lat_s / 3600.0);
if (lat_prefix == 'S')
lt *= -1.0;
if (lt < -90.0 || lt > 90.0)
return 0;
/* attempting to parse the longitude */
consume_blank (p, &p_end);
p = p_end;
if (*p == 'E' || *p == 'W')
{
long_prefix = *p;
p++;
consume_blank (p, &p_end);
p = p_end;
}
if (*p >= '0' && *p <= '9')
{
consume_int (p, &p_end, &long_d);
if (long_d < 0 || long_d > 90)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_deg_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (*p >= '0' && *p <= '9')
{
consume_int (p, &p_end, &long_m);
if (long_m < 0 || long_m >= 60)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_min_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (*p >= '0' && *p <= '9')
{
consume_float (p, &p_end, &long_s);
if (long_s < 0.0 || long_s >= 60.0)
return 0;
p = p_end;
}
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (check_sec_delimiter (p, &p_end))
p = p_end;
else
return 0;
consume_blank (p, &p_end);
p = p_end;
if (long_prefix == '\0')
{
/* attempting to retrieve the prefix */
if (*p == 'E' || *p == 'W')
{
long_prefix = *p;
p++;
}
else
return 0;
}
lg = (double) long_d + ((double) long_m / 60.0) + (long_s / 3600.0);
if (long_prefix == 'W')
lg *= -1.0;
if (lg < -180.0 || lg > 180.0)
return 0;
*longitude = lg;
*latitude = lt;
return 1;
}
GAIAAUX_DECLARE char *
gaiaConvertToDMS (double longitude, double latitude)
{
/* formatting a DMS string */
return gaiaConvertToDMSex (longitude, latitude, 0);
}
GAIAAUX_DECLARE char *
gaiaConvertToDMSex (double longitude, double latitude, int decimal_digits)
{
/* formatting a DMS string */
char *dms0;
char *dms;
char long_prefix = 'E';
char lat_prefix = 'N';
int long_d;
int long_m;
int long_s;
double long_s_dbl;
int lat_d;
int lat_m;
int lat_s;
double lat_s_dbl;
double val;
int len;
if (decimal_digits < 0)
decimal_digits = 0;
if (decimal_digits > 8)
decimal_digits = 8;
if (longitude < -180.0 || longitude > 180.0)
return NULL;
if (latitude < -90.0 || latitude > 90.0)
return NULL;
if (longitude < 0.0)
{
long_prefix = 'W';
longitude *= -1.0;
}
if (latitude < 0.0)
{
lat_prefix = 'S';
latitude *= -1.0;
}
long_d = (int) floor (longitude);
val = 60.0 * (longitude - (double) long_d);
long_m = (int) floor (val);
val = 60.0 * (val - (double) long_m);
long_s_dbl = val;
long_s = (int) floor (val);
if ((val - (double) long_s) > 0.5)
long_s++;
lat_d = (int) floor (latitude);
val = 60.0 * (latitude - (double) lat_d);
lat_m = (int) floor (val);
val = 60.0 * (val - (double) lat_m);
lat_s = (int) floor (val);
lat_s_dbl = val;
if ((val - (double) lat_s) > 0.5)
lat_s++;
if (decimal_digits == 0)
dms0 =
sqlite3_mprintf ("%02d°%02d′%02d″%c %03d°%02d′%02d″%c",
lat_d, lat_m, lat_s, lat_prefix, long_d, long_m,
long_s, long_prefix);
else
{
char format[256];
sprintf (format,
"%%02d°%%02d′%%0%d.%df″%%c %%03d°%%02d′%%0%d.%df″%%c",
decimal_digits + 3, decimal_digits, decimal_digits + 3,
decimal_digits);
dms0 =
sqlite3_mprintf (format, lat_d, lat_m, lat_s_dbl, lat_prefix,
long_d, long_m, long_s_dbl, long_prefix);
}
len = strlen (dms0);
dms = malloc (len + 1);
strcpy (dms, dms0);
sqlite3_free (dms0);
return dms;
}
#if OMIT_ICONV == 0 /* ICONV is absolutely required */
/*********************************************************************
/
/ DISCLAIMER
/
/ the following code implementation (URL percent-encoding/-decoding)
/ simply is a rearranged adaption of this original code released
/ into the Public Domain:
/
/ http://www.geekhideout.com/urlcode.shtml
/
*********************************************************************/
static char
url_to_hex (char code)
{
static char hex[] = "0123456789abcdef";
return hex[code & 15];
}
GAIAAUX_DECLARE char *
gaiaEncodeURL (const char *url, const char *out_charset)
{
/* encoding some URL */
char *encoded = NULL;
const char *in;
char *utf8_url = NULL;
char *out;
int len;
if (url == NULL)
return NULL;
utf8_url = url_fromUtf8 (url, out_charset);
if (utf8_url == NULL)
return NULL;
len = strlen (url);
if (len == 0)
return NULL;
in = utf8_url;
encoded = malloc ((len * 3) + 1);
out = encoded;
while (*in != '\0')
{
if (isalnum (*in) || *in == '-' || *in == '_' || *in == '.'
|| *in == '~')
*out++ = *in;
else
{
*out++ = '%';
*out++ = url_to_hex (*in >> 4);
*out++ = url_to_hex (*in & 15);
}
in++;
}
*out = '\0';
free (utf8_url);
return encoded;
}
static char
url_from_hex (char ch)
{
return isdigit (ch) ? ch - '0' : (char) (tolower (ch) - 'a' + 10);
}
GAIAAUX_DECLARE char *
gaiaDecodeURL (const char *encoded, const char *in_charset)
{
/* decoding some URL */
char *url = NULL;
char *utf8_url = NULL;
const char *in = encoded;
char *out;
int len;
if (encoded == NULL)
return NULL;
len = strlen (encoded);
if (len == 0)
return NULL;
url = malloc (len + 1);
out = url;
while (*in != '\0')
{
if (*in == '%')
{
if (*(in + 1) && *(in + 2))
{
*out++ =
url_from_hex (*(in + 1)) << 4 |
url_from_hex (*(in + 2));
in += 2;
}
}
else if (*in == '+')
*out++ = ' ';
else
*out++ = *in;
in++;
}
*out = '\0';
utf8_url = url_toUtf8 (url, in_charset);
free (url);
return utf8_url;
}
#endif /* ICONV enabled/disabled */
GAIAAUX_DECLARE char *
gaiaDirNameFromPath (const char *path)
{
/* extracting the DirName (if any) from a Path */
const char *in = path;
const char *last = NULL;
int len = 0;
int dirlen = len;
char *name;
if (path == NULL)
return NULL;
while (*in != '\0')
{
/* parsing the Path */
len++;
if (*in == '/' || *in == '\\')
{
last = in;
dirlen = len;
}
in++;
}
if (last == NULL)
return NULL; /* there is no Dir component */
/* allocating the DirName to be returned */
name = malloc (dirlen + 1);
memcpy (name, path, dirlen);
*(name + dirlen) = '\0';
return name;
}
GAIAAUX_DECLARE char *
gaiaFullFileNameFromPath (const char *path)
{
/* extracting the FullFileName (including Extension) from a Path */
const char *in = path;
const char *last = path - 1;
int len;
char *name;
if (path == NULL)
return NULL;
while (*in != '\0')
{
/* parsing the Path */
if (*in == '/' || *in == '\\')
last = in;
in++;
}
len = strlen (last + 1);
if (len == 0)
return NULL;
/* allocating the FullFileName to be returned */
name = malloc (len + 1);
strcpy (name, last + 1);
return name;
}
GAIAAUX_DECLARE char *
gaiaFileNameFromPath (const char *path)
{
/* extracting the FileName (excluding Extension) from a Path */
const char *in = path;
const char *last = path - 1;
int len;
char *name;
int i;
if (path == NULL)
return NULL;
while (*in != '\0')
{
/* parsing the Path */
if (*in == '/' || *in == '\\')
last = in;
in++;
}
len = strlen (last + 1);
if (len == 0)
return NULL;
/* allocating the FullFileName to be returned */
name = malloc (len + 1);
strcpy (name, last + 1);
for (i = len - 1; i > 0; i--)
{
if (*(name + i) == '.')
{
/* stripping out the extension */
*(name + i) = '\0';
break;
}
}
return name;
}
GAIAAUX_DECLARE char *
gaiaFileExtFromPath (const char *path)
{
/* extracting the FileExtension (if any) from a Path */
int len;
char *name;
int i;
int pos = -1;
if (path == NULL)
return NULL;
len = strlen (path);
for (i = len - 1; i > 0; i--)
{
if (*(path + i) == '/' || *(path + i) == '\\')
break;
if (*(path + i) == '.')
{
/* found an extension */
pos = i;
break;
}
}
if (pos <= 0)
return NULL;
/* allocating the FileExtension to be returned */
len = strlen (path + pos + 1);
if (len == 0)
return NULL;
name = malloc (len + 1);
strcpy (name, path + pos + 1);
return name;
}
GAIAAUX_DECLARE char *
gaiaRemoveExtraSpaces (const char *string)
{
/* removing all repeated whitespaces from a string */
int len;
char *clean;
char *p;
int i;
int space = 0;
if (string == NULL)
return NULL;
len = strlen (string);
clean = malloc (len + 1);
p = clean;
for (i = 0; i < len; i++)
{
int sp = 0;
if (string[i] == ' ' || string[i] == '\t')
sp = 1;
else
sp = 0;
if (space && sp)
continue;
*p++ = string[i];
if (sp)
space = 1;
else
space = 0;
}
*p = '\0';
return clean;
}
libspatialite-5.1.0/src/gaiaaux/gg_utf8.c 0000644 0001750 0001750 00000016167 14463127014 015216 0000000 0000000 /*
gg_utf8.c -- locale charset handling
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#if OMIT_ICONV == 0 /* ICONV is absolutely required */
#if defined(__MINGW32__) || defined(_WIN32)
#define LIBICONV_STATIC
#include
#define LIBCHARSET_STATIC
#ifdef _MSC_VER
/* isn't supported on OSGeo4W */
/* applying a tricky workaround to fix this issue */
extern const char *locale_charset (void);
#else /* sane Windows - not OSGeo4W */
#include
#endif /* end localcharset */
#else /* not MINGW32 - WIN32 */
#if defined(__APPLE__) || defined(__ANDROID__)
#include
#include
#else /* neither Mac OsX nor Android */
#include
#include
#endif
#endif
GAIAAUX_DECLARE const char *
gaiaGetLocaleCharset ()
{
/* identifies the locale charset */
#if defined(__MINGW32__) || defined(_WIN32)
return locale_charset ();
#else /* not MINGW32 - WIN32 */
#if defined(__APPLE__) || defined(__ANDROID__)
return locale_charset ();
#else /* neither Mac OsX nor Android */
return nl_langinfo (CODESET);
#endif
#endif
}
GAIAAUX_DECLARE int
gaiaConvertCharset (char **buf, const char *fromCs, const char *toCs)
{
/* converting a string from a charset to another "on-the-fly" */
char *utf8buf;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int maxlen;
iconv_t cvt = iconv_open (toCs, fromCs);
if (cvt == (iconv_t) (-1))
goto unsupported;
len = strlen (*buf);
if (len == 0)
{
/* empty string */
utf8buf = sqlite3_malloc (1);
*utf8buf = '\0';
sqlite3_free (*buf);
*buf = utf8buf;
iconv_close (cvt);
return 1;
}
maxlen = len * 4;
utf8len = maxlen;
pBuf = *buf;
utf8buf = sqlite3_malloc (utf8len);
pUtf8buf = utf8buf;
if (iconv (cvt, &pBuf, &len, &pUtf8buf, &utf8len) == (size_t) (-1))
goto error;
utf8buf[maxlen - utf8len] = '\0';
sqlite3_free (*buf);
*buf = utf8buf;
iconv_close (cvt);
return 1;
error:
iconv_close (cvt);
sqlite3_free (*buf);
*buf = NULL;
unsupported:
return 0;
}
GAIAAUX_DECLARE void *
gaiaCreateUTF8Converter (const char *fromCS)
{
/* creating a UTF8 converter and returning an opaque reference to it */
iconv_t cvt = iconv_open ("UTF-8", fromCS);
if (cvt == (iconv_t) (-1))
return NULL;
return cvt;
}
GAIAAUX_DECLARE void
gaiaFreeUTF8Converter (void *cvtCS)
{
/* destroying a UTF8 converter */
if (cvtCS)
iconv_close (cvtCS);
}
GAIAAUX_DECLARE char *
gaiaConvertToUTF8 (void *cvtCS, const char *buf, int buflen, int *err)
{
/* converting a string to UTF8 */
char *utf8buf = 0;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else
char *pBuf;
#endif
size_t len;
size_t utf8len;
int maxlen = buflen * 4;
char *pUtf8buf;
*err = 0;
if (!cvtCS)
{
*err = 1;
return NULL;
}
utf8buf = malloc (maxlen);
len = buflen;
utf8len = maxlen;
pBuf = (char *) buf;
pUtf8buf = utf8buf;
if (iconv (cvtCS, &pBuf, &len, &pUtf8buf, &utf8len) == (size_t) (-1))
{
free (utf8buf);
*err = 1;
return NULL;
}
utf8buf[maxlen - utf8len] = '\0';
return utf8buf;
}
SPATIALITE_PRIVATE char *
url_toUtf8 (const char *url, const char *in_charset)
{
/* converting an URL to UTF-8 */
iconv_t cvt;
size_t len;
size_t utf8len;
int maxlen;
char *utf8buf;
char *pUtf8buf;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf = url;
#else /* not WIN32 */
char *pBuf = (char *) url;
#endif
if (url == NULL || in_charset == NULL)
return NULL;
cvt = iconv_open ("UTF-8", in_charset);
if (cvt == (iconv_t) (-1))
goto unsupported;
len = strlen (url);
maxlen = len * 4;
utf8len = maxlen;
utf8buf = malloc (maxlen);
pUtf8buf = utf8buf;
if (iconv (cvt, &pBuf, &len, &pUtf8buf, &utf8len) == (size_t) (-1))
goto error;
utf8buf[maxlen - utf8len] = '\0';
iconv_close (cvt);
return utf8buf;
error:
iconv_close (cvt);
free (utf8buf);
unsupported:
return NULL;
}
SPATIALITE_PRIVATE char *
url_fromUtf8 (const char *url, const char *out_charset)
{
/* converting an URL from UTF-8 */
iconv_t cvt;
size_t len;
size_t utf8len;
int maxlen;
char *utf8buf;
char *pUtf8buf;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf = url;
#else /* not WIN32 */
char *pBuf = (char *) url;
#endif
if (url == NULL || out_charset == NULL)
return NULL;
cvt = iconv_open (out_charset, "UTF-8");
if (cvt == (iconv_t) (-1))
goto unsupported;
len = strlen (url);
maxlen = len * 4;
utf8len = maxlen;
utf8buf = malloc (maxlen);
pUtf8buf = utf8buf;
if (iconv (cvt, &pBuf, &len, &pUtf8buf, &utf8len) == (size_t) (-1))
goto error;
utf8buf[maxlen - utf8len] = '\0';
iconv_close (cvt);
return utf8buf;
error:
iconv_close (cvt);
free (utf8buf);
unsupported:
return NULL;
}
#else
GAIAAUX_DECLARE char *
gaiaConvertToUTF8 (void *cvtCS, const char *buf, int buflen, int *err)
{
if (cvtCS == NULL || buf == NULL || err == NULL || buflen == 0)
return NULL;
return NULL;
}
#endif /* ICONV enabled/disabled */
libspatialite-5.1.0/src/gaiaexif/ 0000755 0001750 0001750 00000000000 14463127115 013714 5 0000000 0000000 libspatialite-5.1.0/src/gaiaexif/Makefile.am 0000644 0001750 0001750 00000000720 14463127014 015665 0000000 0000000
AM_CPPFLAGS = -I$(top_srcdir)/src/headers
AM_CPPFLAGS += @CFLAGS@ @CPPFLAGS@
noinst_LTLIBRARIES = libgaiaexif.la gaiaexif.la
libgaiaexif_la_SOURCES = gaia_exif.c
gaiaexif_la_SOURCES = gaia_exif.c
gaiaexif_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I.
gaiaexif_la_CPPFLAGS += @CFLAGS@ @CPPFLAGS@
gaiaexif_la_CPPFLAGS += -DLOADABLE_EXTENSION
gaiaexif_la_LDFLAGS = -module
gaiaexif_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
libspatialite-5.1.0/src/gaiaexif/Makefile.in 0000644 0001750 0001750 00000050464 14463127014 015710 0000000 0000000 # Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/gaiaexif
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./fakeconfig.h \
$(top_builddir)/./config.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig.h \
$(top_builddir)/./config-msvc.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig-msvc.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
gaiaexif_la_LIBADD =
am_gaiaexif_la_OBJECTS = gaiaexif_la-gaia_exif.lo
gaiaexif_la_OBJECTS = $(am_gaiaexif_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
gaiaexif_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(gaiaexif_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(gaiaexif_la_LDFLAGS) \
$(LDFLAGS) -o $@
libgaiaexif_la_LIBADD =
am_libgaiaexif_la_OBJECTS = gaia_exif.lo
libgaiaexif_la_OBJECTS = $(am_libgaiaexif_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/. -I$(top_builddir)/./src/headers/spatialite
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/gaia_exif.Plo \
./$(DEPDIR)/gaiaexif_la-gaia_exif.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(gaiaexif_la_SOURCES) $(libgaiaexif_la_SOURCES)
DIST_SOURCES = $(gaiaexif_la_SOURCES) $(libgaiaexif_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GEOSCONFIG = @GEOSCONFIG@
GEOS_CFLAGS = @GEOS_CFLAGS@
GEOS_LDFLAGS = @GEOS_LDFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/src/headers @CFLAGS@ @CPPFLAGS@
noinst_LTLIBRARIES = libgaiaexif.la gaiaexif.la
libgaiaexif_la_SOURCES = gaia_exif.c
gaiaexif_la_SOURCES = gaia_exif.c
gaiaexif_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I. @CFLAGS@ \
@CPPFLAGS@ -DLOADABLE_EXTENSION
gaiaexif_la_LDFLAGS = -module
gaiaexif_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/gaiaexif/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/gaiaexif/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
gaiaexif.la: $(gaiaexif_la_OBJECTS) $(gaiaexif_la_DEPENDENCIES) $(EXTRA_gaiaexif_la_DEPENDENCIES)
$(AM_V_CCLD)$(gaiaexif_la_LINK) $(gaiaexif_la_OBJECTS) $(gaiaexif_la_LIBADD) $(LIBS)
libgaiaexif.la: $(libgaiaexif_la_OBJECTS) $(libgaiaexif_la_DEPENDENCIES) $(EXTRA_libgaiaexif_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libgaiaexif_la_OBJECTS) $(libgaiaexif_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaia_exif.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiaexif_la-gaia_exif.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
gaiaexif_la-gaia_exif.lo: gaia_exif.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaexif_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaexif_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiaexif_la-gaia_exif.lo -MD -MP -MF $(DEPDIR)/gaiaexif_la-gaia_exif.Tpo -c -o gaiaexif_la-gaia_exif.lo `test -f 'gaia_exif.c' || echo '$(srcdir)/'`gaia_exif.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiaexif_la-gaia_exif.Tpo $(DEPDIR)/gaiaexif_la-gaia_exif.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gaia_exif.c' object='gaiaexif_la-gaia_exif.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiaexif_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiaexif_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiaexif_la-gaia_exif.lo `test -f 'gaia_exif.c' || echo '$(srcdir)/'`gaia_exif.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/gaia_exif.Plo
-rm -f ./$(DEPDIR)/gaiaexif_la-gaia_exif.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gaia_exif.Plo
-rm -f ./$(DEPDIR)/gaiaexif_la-gaia_exif.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
libspatialite-5.1.0/src/gaiaexif/gaia_exif.c 0000644 0001750 0001750 00000211076 14463127014 015721 0000000 0000000 /*
gaia_exif.c -- Gaia EXIF support
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#include
#include
#ifdef _WIN32
#define strcasecmp _stricmp
#endif /* not WIN32 */
static void
exifTagName (char gps, unsigned short tag_id, char *str, int len)
{
/* returns the canonical name corresponding to an EXIF TAG ID */
int l;
char *name = "UNKNOWN";
if (gps)
{
switch (tag_id)
{
case 0x00:
name = "GPSVersionID";
break;
case 0x01:
name = "GPSLatitudeRef";
break;
case 0x02:
name = "GPSLatitude";
break;
case 0x03:
name = "GPSLongitudeRef";
break;
case 0x04:
name = "GPSLongitude";
break;
case 0x05:
name = "GPSAltitudeRef";
break;
case 0x06:
name = "GPSAltitude";
break;
case 0x07:
name = "GPSTimeStamp";
break;
case 0x08:
name = "GPSSatellites";
break;
case 0x09:
name = "GPSStatus";
break;
case 0x0A:
name = "GPSMeasureMode";
break;
case 0x0B:
name = "GPSDOP";
break;
case 0x0C:
name = "GPSSpeedRef";
break;
case 0x0D:
name = "GPSSpeed";
break;
case 0x0E:
name = "GPSTrackRef";
break;
case 0x0F:
name = "GPSTrack";
break;
case 0x10:
name = "GPSImgDirectionRef";
break;
case 0x11:
name = "GPSImgDirection";
break;
case 0x12:
name = "GPSMapDatum";
break;
case 0x13:
name = "GPSDestLatitudeRef";
break;
case 0x14:
name = "GPSDestLatitude";
break;
case 0x15:
name = "GPSDestLongitudeRef";
break;
case 0x16:
name = "GPSDestLongitude";
break;
case 0x17:
name = "GPSDestBearingRef";
break;
case 0x18:
name = "GPSDestBearing";
break;
case 0x19:
name = "GPSDestDistanceRef";
break;
case 0x1A:
name = "GPSDestDistance";
break;
case 0x1B:
name = "GPSProcessingMethod";
break;
case 0x1C:
name = "GPSAreaInformation";
break;
case 0x1D:
name = "GPSDateStamp";
break;
case 0x1E:
name = "GPSDifferential";
break;
};
}
else
{
switch (tag_id)
{
case 0x000B:
name = "ACDComment";
break;
case 0x00FE:
name = "NewSubFile";
break;
case 0x00FF:
name = "SubFile";
break;
case 0x0100:
name = "ImageWidth";
break;
case 0x0101:
name = "ImageLength";
break;
case 0x0102:
name = "BitsPerSample";
break;
case 0x0103:
name = "Compression";
break;
case 0x0106:
name = "PhotometricInterpretation";
break;
case 0x010A:
name = "FillOrder";
break;
case 0x010D:
name = "DocumentName";
break;
case 0x010E:
name = "ImageDescription";
break;
case 0x010F:
name = "Make";
break;
case 0x0110:
name = "Model";
break;
case 0x0111:
name = "StripOffsets";
break;
case 0x0112:
name = "Orientation";
break;
case 0x0115:
name = "SamplesPerPixel";
break;
case 0x0116:
name = "RowsPerStrip";
break;
case 0x0117:
name = "StripByteCounts";
break;
case 0x0118:
name = "MinSampleValue";
break;
case 0x0119:
name = "MaxSampleValue";
break;
case 0x011A:
name = "XResolution";
break;
case 0x011B:
name = "YResolution";
break;
case 0x011C:
name = "PlanarConfiguration";
break;
case 0x011D:
name = "PageName";
break;
case 0x011E:
name = "XPosition";
break;
case 0x011F:
name = "YPosition";
break;
case 0x0120:
name = "FreeOffsets";
break;
case 0x0121:
name = "FreeByteCounts";
break;
case 0x0122:
name = "GrayResponseUnit";
break;
case 0x0123:
name = "GrayResponseCurve";
break;
case 0x0124:
name = "T4Options";
break;
case 0x0125:
name = "T6Options";
break;
case 0x0128:
name = "ResolutionUnit";
break;
case 0x0129:
name = "PageNumber";
break;
case 0x012D:
name = "TransferFunction";
break;
case 0x0131:
name = "Software";
break;
case 0x0132:
name = "DateTime";
break;
case 0x013B:
name = "Artist";
break;
case 0x013C:
name = "HostComputer";
break;
case 0x013D:
name = "Predictor";
break;
case 0x013E:
name = "WhitePoint";
break;
case 0x013F:
name = "PrimaryChromaticities";
break;
case 0x0140:
name = "ColorMap";
break;
case 0x0141:
name = "HalfToneHints";
break;
case 0x0142:
name = "TileWidth";
break;
case 0x0143:
name = "TileLength";
break;
case 0x0144:
name = "TileOffsets";
break;
case 0x0145:
name = "TileByteCounts";
break;
case 0x014A:
name = "SubIFD";
break;
case 0x014C:
name = "InkSet";
break;
case 0x014D:
name = "InkNames";
break;
case 0x014E:
name = "NumberOfInks";
break;
case 0x0150:
name = "DotRange";
break;
case 0x0151:
name = "TargetPrinter";
break;
case 0x0152:
name = "ExtraSample";
break;
case 0x0153:
name = "SampleFormat";
break;
case 0x0154:
name = "SMinSampleValue";
break;
case 0x0155:
name = "SMaxSampleValue";
break;
case 0x0156:
name = "TransferRange";
break;
case 0x0157:
name = "ClipPath";
break;
case 0x0158:
name = "XClipPathUnits";
break;
case 0x0159:
name = "YClipPathUnits";
break;
case 0x015A:
name = "Indexed";
break;
case 0x015B:
name = "JPEGTables";
break;
case 0x015F:
name = "OPIProxy";
break;
case 0x0200:
name = "JPEGProc";
break;
case 0x0201:
name = "JPEGInterchangeFormat";
break;
case 0x0202:
name = "JPEGInterchangeFormatLength";
break;
case 0x0203:
name = "JPEGRestartInterval";
break;
case 0x0205:
name = "JPEGLosslessPredictors";
break;
case 0x0206:
name = "JPEGPointTransforms";
break;
case 0x0207:
name = "JPEGQTables";
break;
case 0x0208:
name = "JPEGDCTables";
break;
case 0x0209:
name = "JPEGACTables";
break;
case 0x0211:
name = "YCbCrCoefficients";
break;
case 0x0212:
name = "YCbCrSubSampling";
break;
case 0x0213:
name = "YCbCrPositioning";
break;
case 0x0214:
name = "ReferenceBlackWhite";
break;
case 0x02BC:
name = "ExtensibleMetadataPlatform";
break;
case 0x0301:
name = "Gamma";
break;
case 0x0302:
name = "ICCProfileDescriptor";
break;
case 0x0303:
name = "SRGBRenderingIntent";
break;
case 0x0320:
name = "ImageTitle";
break;
case 0x5001:
name = "ResolutionXUnit";
break;
case 0x5002:
name = "ResolutionYUnit";
break;
case 0x5003:
name = "ResolutionXLengthUnit";
break;
case 0x5004:
name = "ResolutionYLengthUnit";
break;
case 0x5005:
name = "PrintFlags";
break;
case 0x5006:
name = "PrintFlagsVersion";
break;
case 0x5007:
name = "PrintFlagsCrop";
break;
case 0x5008:
name = "PrintFlagsBleedWidth";
break;
case 0x5009:
name = "PrintFlagsBleedWidthScale";
break;
case 0x500A:
name = "HalftoneLPI";
break;
case 0x500B:
name = "HalftoneLPIUnit";
break;
case 0x500C:
name = "HalftoneDegree";
break;
case 0x500D:
name = "HalftoneShape";
break;
case 0x500E:
name = "HalftoneMisc";
break;
case 0x500F:
name = "HalftoneScreen";
break;
case 0x5010:
name = "JPEGQuality";
break;
case 0x5011:
name = "GridSize";
break;
case 0x5012:
name = "ThumbnailFormat";
break;
case 0x5013:
name = "ThumbnailWidth";
break;
case 0x5014:
name = "ThumbnailHeight";
break;
case 0x5015:
name = "ThumbnailColorDepth";
break;
case 0x5016:
name = "ThumbnailPlanes";
break;
case 0x5017:
name = "ThumbnailRawBytes";
break;
case 0x5018:
name = "ThumbnailSize";
break;
case 0x5019:
name = "ThumbnailCompressedSize";
break;
case 0x501A:
name = "ColorTransferFunction";
break;
case 0x501B:
name = "ThumbnailData";
break;
case 0x5020:
name = "ThumbnailImageWidth";
break;
case 0x5021:
name = "ThumbnailImageHeight";
break;
case 0x5022:
name = "ThumbnailBitsPerSample";
break;
case 0x5023:
name = "ThumbnailCompression";
break;
case 0x5024:
name = "ThumbnailPhotometricInterp";
break;
case 0x5025:
name = "ThumbnailImageDescription";
break;
case 0x5026:
name = "ThumbnailEquipMake";
break;
case 0x5027:
name = "ThumbnailEquipModel";
break;
case 0x5028:
name = "ThumbnailStripOffsets";
break;
case 0x5029:
name = "ThumbnailOrientation";
break;
case 0x502A:
name = "ThumbnailSamplesPerPixel";
break;
case 0x502B:
name = "ThumbnailRowsPerStrip";
break;
case 0x502C:
name = "ThumbnailStripBytesCount";
break;
case 0x502D:
name = "ThumbnailResolutionX";
break;
case 0x502E:
name = "ThumbnailResolutionY";
break;
case 0x502F:
name = "ThumbnailPlanarConfig";
break;
case 0x5030:
name = "ThumbnailResolutionUnit";
break;
case 0x5031:
name = "ThumbnailTransferFunction";
break;
case 0x5032:
name = "ThumbnailSoftwareUsed";
break;
case 0x5033:
name = "ThumbnailDateTime";
break;
case 0x5034:
name = "ThumbnailArtist";
break;
case 0x5035:
name = "ThumbnailWhitePoint";
break;
case 0x5036:
name = "ThumbnailPrimaryChromaticities";
break;
case 0x5037:
name = "ThumbnailYCbCrCoefficients";
break;
case 0x5038:
name = "ThumbnailYCbCrSubsampling";
break;
case 0x5039:
name = "ThumbnailYCbCrPositioning";
break;
case 0x503A:
name = "ThumbnailRefBlackWhite";
break;
case 0x503B:
name = "ThumbnailCopyRight";
break;
case 0x5090:
name = "LuminanceTable";
break;
case 0x5091:
name = "ChrominanceTable";
break;
case 0x5100:
name = "FrameDelay";
break;
case 0x5101:
name = "LoopCount";
break;
case 0x5110:
name = "PixelUnit";
break;
case 0x5111:
name = "PixelPerUnitX";
break;
case 0x5112:
name = "PixelPerUnitY";
break;
case 0x5113:
name = "PaletteHistogram";
break;
case 0x1000:
name = "RelatedImageFileFormat";
break;
case 0x800D:
name = "ImageID";
break;
case 0x80E3:
name = "Matteing";
break;
case 0x80E4:
name = "DataType";
break;
case 0x80E5:
name = "ImageDepth";
break;
case 0x80E6:
name = "TileDepth";
break;
case 0x828D:
name = "CFARepeatPatternDim";
break;
case 0x828E:
name = "CFAPattern";
break;
case 0x828F:
name = "BatteryLevel";
break;
case 0x8298:
name = "Copyright";
break;
case 0x829A:
name = "ExposureTime";
break;
case 0x829D:
name = "FNumber";
break;
case 0x83BB:
name = "IPTC/NAA";
break;
case 0x84E3:
name = "IT8RasterPadding";
break;
case 0x84E5:
name = "IT8ColorTable";
break;
case 0x8649:
name = "ImageResourceInformation";
break;
case 0x8769:
name = "Exif IFD Pointer";
break;
case 0x8773:
name = "ICC_Profile";
break;
case 0x8822:
name = "ExposureProgram";
break;
case 0x8824:
name = "SpectralSensitivity";
break;
case 0x8825:
name = "GPSInfo IFD Pointer";
break;
case 0x8827:
name = "ISOSpeedRatings";
break;
case 0x8828:
name = "OECF";
break;
case 0x9000:
name = "ExifVersion";
break;
case 0x9003:
name = "DateTimeOriginal";
break;
case 0x9004:
name = "DateTimeDigitized";
break;
case 0x9101:
name = "ComponentsConfiguration";
break;
case 0x9102:
name = "CompressedBitsPerPixel";
break;
case 0x9201:
name = "ShutterSpeedValue";
break;
case 0x9202:
name = "ApertureValue";
break;
case 0x9203:
name = "BrightnessValue";
break;
case 0x9204:
name = "ExposureBiasValue";
break;
case 0x9205:
name = "MaxApertureValue";
break;
case 0x9206:
name = "SubjectDistance";
break;
case 0x9207:
name = "MeteringMode";
break;
case 0x9208:
name = "LightSource";
break;
case 0x9209:
name = "Flash";
break;
case 0x920A:
name = "FocalLength";
break;
case 0x920B:
case 0xA20B:
name = "FlashEnergy";
break;
case 0x920C:
case 0xA20C:
name = "SpatialFrequencyResponse";
break;
case 0x920D:
name = "Noise";
break;
case 0x920E:
case 0xA20E:
name = "FocalPlaneXResolution";
break;
case 0x920F:
case 0XA20F:
name = "FocalPlaneYResolution";
break;
case 0x9210:
case 0xA210:
name = "FocalPlaneResolutionUnit";
break;
case 0x9211:
name = "ImageNumber";
break;
case 0x9212:
name = "SecurityClassification";
break;
case 0x9213:
name = "ImageHistory";
break;
case 0x9214:
case 0xA214:
name = "SubjectLocation";
break;
case 0x9215:
case 0xA215:
name = "ExposureIndex";
break;
case 0x9216:
name = "TIFF/EPStandardID";
break;
case 0x9217:
case 0xA217:
name = "SensingMethod";
break;
case 0x923F:
name = "StoNits";
break;
case 0x927C:
name = "MakerNote";
break;
case 0x9286:
name = "UserComment";
break;
case 0x9290:
name = "SubSecTime";
break;
case 0x9291:
name = "SubSecTimeOriginal";
break;
case 0x9292:
name = "SubSecTimeDigitized";
break;
case 0xA000:
name = "FlashpixVersion";
break;
case 0xA001:
name = "ColorSpace";
break;
case 0xA002:
name = "ExifImageWidth";
break;
case 0xA003:
name = "ExifImageLength";
break;
case 0xA004:
name = "RelatedSoundFile";
break;
case 0xA005:
name = "Interoperability IFD Pointer";
break;
case 0xA20D:
name = "Noise";
break;
case 0xA211:
name = "ImageNumber";
break;
case 0xA212:
name = "SecurityClassification";
break;
case 0xA213:
name = "ImageHistory";
break;
case 0xA216:
name = "TIFF/EPStandardID";
break;
case 0xA300:
name = "FileSource";
break;
case 0xA301:
name = "SceneType";
break;
case 0xA302:
name = "CFAPattern";
break;
case 0xA401:
name = "CustomRendered";
break;
case 0xA402:
name = "ExposureMode";
break;
case 0xA403:
name = "WhiteBalance";
break;
case 0xA404:
name = "DigitalZoomRatio";
break;
case 0xA405:
name = "FocalLengthIn35mmFilm";
break;
case 0xA406:
name = "SceneCaptureType";
break;
case 0xA407:
name = "GainControl";
break;
case 0xA408:
name = "Contrast";
break;
case 0xA409:
name = "Saturation";
break;
case 0xA40A:
name = "Sharpness";
break;
case 0xA40B:
name = "DeviceSettingDescription";
break;
case 0xA40C:
name = "SubjectDistanceRange";
break;
case 0xA420:
name = "ImageUniqueID";
break;
};
}
l = strlen (name);
if (len > l)
strcpy (str, name);
else
{
memset (str, '\0', len);
memcpy (str, name, len - 1);
}
}
static unsigned short
exifImportU16 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches an unsigned 16bit int from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[2];
unsigned short short_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 1);
convert.byte[1] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 1);
convert.byte[1] = *(p + 0);
}
}
return convert.short_value;
}
static unsigned int
exifImportU32 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches an unsigned 32bit int from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
unsigned int int_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
}
return convert.int_value;
}
static float
exifImportFloat32 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches a 32bit FLOAT from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
float float_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
}
return convert.float_value;
}
static void
exifSetTagValue (gaiaExifTagPtr tag, const unsigned char *blob, int endian_mode,
int endian_arch, int app1_offset)
{
/* setting the TAG value */
int i;
int sz = 0;
unsigned int offset;
const unsigned char *ptr;
unsigned short short_value;
unsigned int int_value;
short sign_short_value;
int sign_int_value;
float float_value;
double double_value;
if (tag->Type == 1 || tag->Type == 2 || tag->Type == 6 || tag->Type == 7)
sz = tag->Count;
if (tag->Type == 3 || tag->Type == 8)
sz = tag->Count * 2;
if (tag->Type == 4 || tag->Type == 9 || tag->Type == 11)
sz = tag->Count * 4;
if (tag->Type == 5 || tag->Type == 10 || tag->Type == 12)
sz = tag->Count * 8;
if (sz <= 4)
{
/* TAG values is stored within the offset */
ptr = tag->TagOffset;
}
else
{
/* jumping to offset */
offset = exifImportU32 (tag->TagOffset, endian_mode, endian_arch);
offset += app1_offset + 10;
ptr = blob + offset;
}
if (tag->Type == 1 || tag->Type == 6 || tag->Type == 7)
{
/* BYTE type */
tag->ByteValue = malloc (tag->Count);
memcpy (tag->ByteValue, ptr, tag->Count);
}
if (tag->Type == 2)
{
/* STRING type */
tag->StringValue = malloc (tag->Count);
memcpy (tag->StringValue, ptr, tag->Count);
}
if (tag->Type == 3)
{
/* SHORT type */
tag->ShortValues = malloc (tag->Count * sizeof (unsigned short));
for (i = 0; i < tag->Count; i++)
{
short_value =
exifImportU16 (ptr + (i * 2), endian_mode, endian_arch);
*(tag->ShortValues + i) = short_value;
}
}
if (tag->Type == 4)
{
/* LONG type */
tag->LongValues = malloc (tag->Count * sizeof (unsigned int));
for (i = 0; i < tag->Count; i++)
{
int_value =
exifImportU32 (ptr + (i * 4), endian_mode, endian_arch);
*(tag->LongValues + i) = int_value;
}
}
if (tag->Type == 5)
{
/* RATIONAL type */
tag->LongRationals1 = malloc (tag->Count * sizeof (unsigned int));
tag->LongRationals2 = malloc (tag->Count * sizeof (unsigned int));
for (i = 0; i < tag->Count; i++)
{
int_value =
exifImportU32 (ptr + (i * 8), endian_mode, endian_arch);
*(tag->LongRationals1 + i) = int_value;
int_value =
exifImportU32 (ptr + (i * 8) + 4, endian_mode, endian_arch);
*(tag->LongRationals2 + i) = int_value;
}
}
if (tag->Type == 8)
{
/* SSHORT type */
tag->SignedShortValues = malloc (tag->Count * sizeof (short));
for (i = 0; i < tag->Count; i++)
{
sign_short_value =
gaiaImport16 (ptr + (i * 2), endian_mode, endian_arch);
*(tag->SignedShortValues + i) = sign_short_value;
}
}
if (tag->Type == 9)
{
/* SIGNED LONG type */
tag->SignedLongValues = malloc (tag->Count * sizeof (int));
for (i = 0; i < tag->Count; i++)
{
sign_int_value =
gaiaImport32 (ptr + (i * 4), endian_mode, endian_arch);
*(tag->SignedLongValues + i) = sign_int_value;
}
}
if (tag->Type == 10)
{
/* SIGNED RATIONAL type */
tag->SignedLongRationals1 = malloc (tag->Count * sizeof (int));
tag->SignedLongRationals2 = malloc (tag->Count * sizeof (int));
for (i = 0; i < tag->Count; i++)
{
sign_int_value =
gaiaImport32 (ptr + (i * 8), endian_mode, endian_arch);
*(tag->SignedLongRationals1 + i) = sign_int_value;
sign_int_value =
gaiaImport32 (ptr + (i * 8) + 4, endian_mode, endian_arch);
*(tag->SignedLongRationals2 + i) = sign_int_value;
}
}
if (tag->Type == 11)
{
/* FLOAT type */
tag->FloatValues = malloc (tag->Count * sizeof (float));
for (i = 0; i < tag->Count; i++)
{
float_value =
exifImportFloat32 (ptr + (i * 4), endian_mode, endian_arch);
*(tag->FloatValues + i) = float_value;
}
}
if (tag->Type == 12)
{
/* DOUBLE type */
tag->DoubleValues = malloc (tag->Count * sizeof (double));
for (i = 0; i < tag->Count; i++)
{
double_value =
gaiaImport64 (ptr + (i * 8), endian_mode, endian_arch);
*(tag->DoubleValues + i) = double_value;
}
}
}
static void
exifParseTag (const unsigned char *blob, unsigned int offset, int endian_mode,
int endian_arch, gaiaExifTagListPtr list, int gps,
int app1_offset)
{
/* parsing some TAG and inserting into the list */
unsigned short tag_id;
unsigned short type;
unsigned int count;
gaiaExifTagPtr tag;
tag_id = exifImportU16 (blob + offset, endian_mode, endian_arch);
type = exifImportU16 (blob + offset + 2, endian_mode, endian_arch);
count = exifImportU32 (blob + offset + 4, endian_mode, endian_arch);
tag = malloc (sizeof (gaiaExifTag));
tag->Gps = (char) gps;
tag->TagId = tag_id;
tag->Type = type;
tag->Count = (unsigned short) count;
memcpy (tag->TagOffset, blob + offset + 8, 4);
tag->ByteValue = NULL;
tag->StringValue = NULL;
tag->ShortValues = NULL;
tag->LongValues = NULL;
tag->LongRationals1 = NULL;
tag->LongRationals2 = NULL;
tag->SignedShortValues = NULL;
tag->SignedLongValues = NULL;
tag->SignedLongRationals1 = NULL;
tag->SignedLongRationals2 = NULL;
tag->FloatValues = NULL;
tag->DoubleValues = NULL;
exifSetTagValue (tag, blob, endian_mode, endian_arch, app1_offset);
tag->Next = NULL;
if (!(list->First))
list->First = tag;
if (list->Last)
(list->Last)->Next = tag;
list->Last = tag;
(list->NumTags)++;
}
static void
exifExpandIFD (gaiaExifTagListPtr list, const unsigned char *blob,
int endian_mode, int endian_arch, int app1_offset)
{
/* trying to expand the EXIF-IFD */
unsigned int offset;
unsigned short items;
unsigned short i;
gaiaExifTagPtr tag;
if (!list)
return;
tag = list->First;
while (tag)
{
if (tag->TagId == 34665)
{
/* ok, this one is an IFD pointer */
offset =
exifImportU32 (tag->TagOffset, endian_mode, endian_arch);
offset += app1_offset + 10;
items = exifImportU16 (blob + offset, endian_mode, endian_arch);
offset += 2;
for (i = 0; i < items; i++)
{
/* fetching the TAGs */
exifParseTag (blob, offset, endian_mode, endian_arch,
list, 0, app1_offset);
offset += 12;
}
}
tag = tag->Next;
}
}
static void
exifExpandGPS (gaiaExifTagListPtr list, const unsigned char *blob,
int endian_mode, int endian_arch, int app1_offset)
{
/* trying to expand the EXIF-GPS */
unsigned int offset;
unsigned short items;
unsigned short i;
gaiaExifTagPtr tag;
if (!list)
return;
tag = list->First;
while (tag)
{
if (tag->TagId == 34853)
{
/* ok, this one is a GPSinfo-IFD pointer */
offset =
exifImportU32 (tag->TagOffset, endian_mode, endian_arch);
offset += app1_offset + 10;
items = exifImportU16 (blob + offset, endian_mode, endian_arch);
offset += 2;
for (i = 0; i < items; i++)
{
/* fetching the TAGs */
exifParseTag (blob, offset, endian_mode, endian_arch,
list, 1, app1_offset);
offset += 12;
}
}
tag = tag->Next;
}
}
GAIAEXIF_DECLARE gaiaExifTagListPtr
gaiaGetExifTags (const unsigned char *blob, int size)
{
/* trying to parse a BLOB as an EXIF photo */
gaiaExifTagListPtr list;
int endian_arch = gaiaEndianArch ();
int endian_mode;
unsigned short app1_size;
unsigned int offset;
unsigned short items;
unsigned short i;
int app1_offset;
gaiaExifTagPtr pT;
if (!blob)
goto error;
if (size < 14)
goto error;
/* checking for SOI [Start Of Image] */
if (*(blob + 0) == 0xff && *(blob + 1) == 0xd8)
;
else
goto error;
for (app1_offset = 2; app1_offset < size - 1; app1_offset++)
{
if (*(blob + app1_offset) == 0xff
&& *(blob + app1_offset + 1) == 0xe1)
{
/* found APP1 marker */
break;
}
}
if (app1_offset == size - 1)
{
/* we've reached the end of the file, but not found the marker */
goto error;
}
/* checking for EXIF identifier */
if (memcmp (blob + app1_offset + 4, "Exif", 4) == 0)
;
else
goto error;
/* checking for Pad */
if (*(blob + app1_offset + 8) == 0x00 && *(blob + app1_offset + 9) == 0x00)
;
else
goto error;
if (memcmp (blob + app1_offset + 10, "II", 2) == 0)
endian_mode = GAIA_LITTLE_ENDIAN;
else if (memcmp (blob + app1_offset + 10, "MM", 2) == 0)
endian_mode = GAIA_BIG_ENDIAN;
else
goto error;
/* OK: this BLOB seems to contain a valid EXIF */
app1_size =
exifImportU16 (blob + app1_offset + 2, endian_mode, endian_arch);
if ((app1_size + app1_offset + 4) > size)
goto error;
/* checking for marker */
if (endian_mode == GAIA_BIG_ENDIAN)
{
if (*(blob + app1_offset + 12) == 0x00
&& *(blob + app1_offset + 13) == 0x2a)
;
else
goto error;
}
else
{
if (*(blob + app1_offset + 12) == 0x2a
&& *(blob + app1_offset + 13) == 0x00)
;
else
goto error;
}
/* allocating an EXIF TAG LIST */
list = malloc (sizeof (gaiaExifTagList));
list->First = NULL;
list->Last = NULL;
list->NumTags = 0;
list->TagsArray = NULL;
offset = exifImportU32 (blob + app1_offset + 14, endian_mode, endian_arch);
offset += app1_offset + 10;
/* jump to offset */
items = exifImportU16 (blob + offset, endian_mode, endian_arch);
offset += 2;
for (i = 0; i < items; i++)
{
/* fetching the EXIF TAGs */
exifParseTag (blob, offset, endian_mode, endian_arch, list, 0,
app1_offset);
offset += 12;
}
/* expanding the IFD and GPS tags */
exifExpandIFD (list, blob, endian_mode, endian_arch, app1_offset);
exifExpandGPS (list, blob, endian_mode, endian_arch, app1_offset);
if (list->NumTags)
{
/* organizing the EXIF TAGS as an Array */
list->TagsArray = malloc (sizeof (gaiaExifTagPtr) * list->NumTags);
pT = list->First;
i = 0;
while (pT)
{
*(list->TagsArray + i++) = pT;
pT = pT->Next;
}
}
return list;
error:
return NULL;
}
GAIAEXIF_DECLARE void
gaiaExifTagsFree (gaiaExifTagListPtr p)
{
/* memory cleanup; freeing the EXIF TAG list */
gaiaExifTagPtr pT;
gaiaExifTagPtr pTn;
if (!p)
return;
pT = p->First;
while (pT)
{
pTn = pT->Next;
if (pT->ByteValue)
free (pT->ByteValue);
if (pT->StringValue)
free (pT->StringValue);
if (pT->ShortValues)
free (pT->ShortValues);
if (pT->LongValues)
free (pT->LongValues);
if (pT->LongRationals1)
free (pT->LongRationals1);
if (pT->LongRationals2)
free (pT->LongRationals2);
if (pT->SignedShortValues)
free (pT->SignedShortValues);
if (pT->SignedLongValues)
free (pT->SignedLongValues);
if (pT->SignedLongRationals1)
free (pT->SignedLongRationals1);
if (pT->SignedLongRationals2)
free (pT->SignedLongRationals2);
if (pT->FloatValues)
free (pT->FloatValues);
if (pT->DoubleValues)
free (pT->DoubleValues);
free (pT);
pT = pTn;
}
if (p->TagsArray)
free (p->TagsArray);
free (p);
}
GAIAEXIF_DECLARE int
gaiaGetExifTagsCount (gaiaExifTagListPtr tag_list)
{
/* returns the # TAGSs into this list */
return tag_list->NumTags;
}
GAIAEXIF_DECLARE gaiaExifTagPtr
gaiaGetExifTagByPos (gaiaExifTagListPtr tag_list, const int pos)
{
/* returns the Nth TAG from this list */
if (pos >= 0 && pos < tag_list->NumTags)
return *(tag_list->TagsArray + pos);
return NULL;
}
GAIAEXIF_DECLARE gaiaExifTagPtr
gaiaGetExifTagById (const gaiaExifTagListPtr tag_list,
const unsigned short tag_id)
{
/* returns a not-GPS TAG identified by its ID */
gaiaExifTagPtr pT = tag_list->First;
while (pT)
{
if (!(pT->Gps) && pT->TagId == tag_id)
return pT;
pT = pT->Next;
}
return NULL;
}
GAIAEXIF_DECLARE gaiaExifTagPtr
gaiaGetExifGpsTagById (const gaiaExifTagListPtr tag_list,
const unsigned short tag_id)
{
/* returns a GPS TAG identified by its ID */
gaiaExifTagPtr pT = tag_list->First;
while (pT)
{
if (pT->Gps && pT->TagId == tag_id)
return pT;
pT = pT->Next;
}
return NULL;
}
GAIAEXIF_DECLARE gaiaExifTagPtr
gaiaGetExifTagByName (const gaiaExifTagListPtr tag_list, const char *tag_name)
{
/* returns a TAG identified by its Name */
char name[128];
gaiaExifTagPtr pT = tag_list->First;
while (pT)
{
exifTagName (pT->Gps, pT->TagId, name, 128);
if (strcasecmp (name, tag_name) == 0)
return pT;
pT = pT->Next;
}
return NULL;
}
GAIAEXIF_DECLARE unsigned short
gaiaExifTagGetId (const gaiaExifTagPtr tag)
{
/* returns the TAG ID */
return tag->TagId;
}
GAIAEXIF_DECLARE int
gaiaIsExifGpsTag (const gaiaExifTagPtr tag)
{
/* checks if this one is a GPS tag */
return tag->Gps;
}
GAIAEXIF_DECLARE void
gaiaExifTagGetName (const gaiaExifTagPtr tag, char *str, int len)
{
/* returns the TAG symbolic Name */
exifTagName (tag->Gps, tag->TagId, str, len);
}
GAIAEXIF_DECLARE unsigned short
gaiaExifTagGetValueType (const gaiaExifTagPtr tag)
{
/* returns the TAG value Type */
return tag->Type;
}
GAIAEXIF_DECLARE unsigned short
gaiaExifTagGetNumValues (const gaiaExifTagPtr tag)
{
/* returns the # TAG Values */
return tag->Count;
}
GAIAEXIF_DECLARE unsigned char
gaiaExifTagGetByteValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Byte value */
if (ind >= 0
&& ind <
tag->Count && (tag->Type == 1 || tag->Type == 6 || tag->Type == 7))
{
*ok = 1;
return *(tag->ByteValue + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE void
gaiaExifTagGetStringValue (const gaiaExifTagPtr tag, char *str, int len,
int *ok)
{
/* returns the String value */
int l;
if (tag->Type == 2)
{
*ok = 1;
l = strlen (tag->StringValue);
if (len > l)
strcpy (str, tag->StringValue);
else
{
memset (str, '\0', len);
memcpy (str, tag->StringValue, len - 1);
}
return;
}
*ok = 0;
}
GAIAEXIF_DECLARE unsigned short
gaiaExifTagGetShortValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Short value */
if (ind >= 0 && ind < tag->Count && tag->Type == 3)
{
*ok = 1;
return *(tag->ShortValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE unsigned int
gaiaExifTagGetLongValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Long value */
if (ind >= 0 && ind < tag->Count && tag->Type == 4)
{
*ok = 1;
return *(tag->LongValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE unsigned int
gaiaExifTagGetRational1Value (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Rational (1) value */
if (ind >= 0 && ind < tag->Count && tag->Type == 5)
{
*ok = 1;
return *(tag->LongRationals1 + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE unsigned int
gaiaExifTagGetRational2Value (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Rational (2) value */
if (ind >= 0 && ind < tag->Count && tag->Type == 5)
{
*ok = 1;
return *(tag->LongRationals2 + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE double
gaiaExifTagGetRationalValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Rational value as Double */
double x;
if (ind >= 0
&& ind < tag->Count && tag->Type == 5 && *(tag->LongRationals2 + ind))
{
*ok = 1;
x = (double) (*(tag->LongRationals1 + ind)) /
(double) (*(tag->LongRationals2 + ind));
return x;
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE short
gaiaExifTagGetSignedShortValue (const gaiaExifTagPtr tag, const int ind,
int *ok)
{
/* returns the Nth Signed Short value */
if (ind >= 0 && ind < tag->Count && tag->Type == 8)
{
*ok = 1;
return *(tag->SignedShortValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE int
gaiaExifTagGetSignedLongValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Signed Long value */
if (ind >= 0 && ind < tag->Count && tag->Type == 9)
{
*ok = 1;
return *(tag->SignedLongValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE int
gaiaExifTagGetSignedRational1Value (const gaiaExifTagPtr tag, const int ind,
int *ok)
{
/* returns the Nth Signed Rational (1) value */
if (ind >= 0 && ind < tag->Count && tag->Type == 10)
{
*ok = 1;
return *(tag->SignedLongRationals1 + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE int
gaiaExifTagGetSignedRational2Value (const gaiaExifTagPtr tag, const int ind,
int *ok)
{
/* returns the Nth Signed Rational (2) value */
if (ind >= 0 && ind < tag->Count && tag->Type == 10)
{
*ok = 1;
return *(tag->SignedLongRationals2 + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE double
gaiaExifTagGetSignedRationalValue (const gaiaExifTagPtr tag, const int ind,
int *ok)
{
/* returns the Nth Signed Rational value as Double */
double x;
if (ind >= 0
&& ind <
tag->Count && tag->Type == 10 && *(tag->SignedLongRationals2 + ind))
{
*ok = 1;
x = (double) (*(tag->SignedLongRationals1 + ind)) /
(double) (*(tag->SignedLongRationals2 + ind));
return x;
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE float
gaiaExifTagGetFloatValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Float value */
if (ind >= 0 && ind < tag->Count && tag->Type == 11)
{
*ok = 1;
return *(tag->FloatValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE double
gaiaExifTagGetDoubleValue (const gaiaExifTagPtr tag, const int ind, int *ok)
{
/* returns the Nth Double value */
if (ind >= 0 && ind < tag->Count && tag->Type == 12)
{
*ok = 1;
return *(tag->DoubleValues + ind);
}
*ok = 0;
return 0;
}
GAIAEXIF_DECLARE void
gaiaExifTagGetHumanReadable (const gaiaExifTagPtr tag, char *str, int len,
int *ok)
{
/* returns the Human Readable value */
char *human = "";
char dummy[1024];
int l;
int xok;
double dblval;
switch (tag->TagId)
{
case 0x0128: /* ResolutionUnit */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 2:
human = "Inches";
break;
case 3:
human = "Centimeters";
break;
};
}
break;
case 0x8822: /* ExposureProgram */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Not defined";
break;
case 1:
human = "Manual";
break;
case 2:
human = "Normal program";
break;
case 3:
human = "Aperture priority";
break;
case 4:
human = "Shutter priority";
break;
case 5:
human = "Creative program (biased toward depth of field)";
break;
case 6:
human =
"Action program (biased toward fast shutter speed)";
break;
case 7:
human =
"Portrait mode (for closeup photos with the background out of focus)";
break;
case 8:
human =
"Landscape mode (for landscape photos with the background in focus)";
break;
};
}
break;
case 0xA402: /* ExposureMode */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Auto exposure";
break;
case 1:
human = "Manual exposure";
break;
case 2:
human = "Auto bracket";
break;
};
}
break;
case 0x0112: /* Orientation */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 1:
human = "Normal";
break;
case 2:
human = "Mirrored";
break;
case 3:
human = "Upsidedown";
break;
case 4:
human = "Upsidedown Mirrored";
break;
case 5:
human = "90 deg Clockwise Mirrored";
break;
case 6:
human = "90 deg Counterclocwise";
break;
case 7:
human = "90 deg Counterclocwise Mirrored";
break;
case 8:
human = "90 deg Mirrored";
break;
};
}
break;
case 0x9207: /* MeteringMode */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 1:
human = "Average";
break;
case 2:
human = "Center Weighted Average";
break;
case 3:
human = "Spot";
break;
case 4:
human = "MultiSpot";
break;
case 5:
human = "MultiSegment";
break;
case 6:
human = "Partial";
break;
case 255:
human = "Other";
break;
};
}
break;
case 0xA403: /* WhiteBalance */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Auto";
break;
case 1:
human = "Sunny";
break;
case 2:
human = "Cloudy";
break;
case 3:
human = "Tungsten";
break;
case 4:
human = "Fluorescent";
break;
case 5:
human = "Flash";
break;
case 6:
human = "Custom";
break;
case 129:
human = "Manual";
break;
};
}
break;
case 0x9209: /* Flash */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
case 16:
case 24:
case 32:
human = "No Flash";
break;
case 1:
human = "Flash";
break;
case 5:
human = "Flash, strobe return light not detected";
break;
case 7:
human = "Flash, strobe return light detected";
break;
case 9:
human = "Compulsory Flash";
break;
case 13:
human = "Compulsory Flash, Return light not detected";
break;
case 15:
human = "Compulsory Flash, Return light detected";
break;
case 25:
human = "Flash, Auto-Mode";
break;
case 29:
human = "Flash, Auto-Mode, Return light not detected";
break;
case 31:
human = "Flash, Auto-Mode, Return light detected";
break;
case 65:
human = "Red Eye";
break;
case 69:
human = "Red Eye, Return light not detected";
break;
case 71:
human = "Red Eye, Return light detected";
break;
case 73:
human = "Red Eye, Compulsory Flash";
break;
case 77:
human =
"Red Eye, Compulsory Flash, Return light not detected";
break;
case 79:
human =
"Red Eye, Compulsory Flash, Return light detected";
break;
case 89:
human = "Red Eye, Auto-Mode";
break;
case 93:
human = "Red Eye, Auto-Mode, Return light not detected";
break;
case 95:
human = "Red Eye, Auto-Mode, Return light detected";
break;
};
}
break;
case 0xA217: /* SensingMethod */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 1:
human = "Not defined";
break;
case 2:
human = "One Chip Color Area Sensor";
break;
case 3:
human = "Two Chip Color Area Sensor";
break;
case 4:
human = "Three Chip Color Area Sensor";
break;
case 5:
human = "Color Sequential Area Sensor";
break;
case 7:
human = "Trilinear Sensor";
break;
case 8:
human = "Color Sequential Linear Sensor";
break;
};
}
break;
case 0xA406: /* SceneCaptureType */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Standard";
break;
case 1:
human = "Landscape";
break;
case 2:
human = "Portrait";
break;
case 3:
human = "Night scene";
break;
};
}
break;
case 0xA407: /* GainControl */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "None";
break;
case 1:
human = "Low gain up";
break;
case 2:
human = "High gain up";
break;
case 3:
human = "Low gain down";
break;
case 4:
human = "High gain down";
break;
};
}
break;
case 0xA408: /* Contrast */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Normal";
break;
case 1:
human = "Soft";
break;
case 2:
human = "Hard";
break;
};
}
break;
case 0xA409: /* Saturation */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Normal";
break;
case 1:
human = "Low saturation";
break;
case 2:
human = "High saturation";
break;
};
}
break;
case 0xA40A: /* Sharpness */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Normal";
break;
case 1:
human = "Soft";
break;
case 2:
human = "Hard";
break;
};
}
break;
case 0xA40C: /* SubjectDistanceRange */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Unknown";
break;
case 1:
human = "Macro";
break;
case 2:
human = "Close view";
break;
case 3:
human = "Distant view";
break;
};
}
break;
case 0x9208: /* LightSource */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 0:
human = "Unknown";
break;
case 1:
human = "Daylight";
break;
case 2:
human = "Fluorescent";
break;
case 3:
human = "Tungsten (incandescent light)";
break;
case 4:
human = "Flash";
break;
case 9:
human = "Fine weather";
break;
case 10:
human = "Cloudy weather";
break;
case 11:
human = "Shade";
break;
case 12:
human = "Daylight fluorescent (D 5700 - 7100K)";
break;
case 13:
human = "Day white fluorescent (N 4600 - 5400K)";
break;
case 14:
human = "Cool white fluorescent (W 3900 - 4500K)";
break;
case 15:
human = "White fluorescent (WW 3200 - 3700K)";
break;
case 17:
human = "Standard light A";
break;
case 18:
human = "Standard light B";
break;
case 19:
human = "Standard light C";
break;
case 20:
human = "D55";
break;
case 21:
human = "D65";
break;
case 22:
human = "D75";
break;
case 23:
human = "D50";
break;
case 24:
human = "ISO studio tungsten";
break;
case 255:
human = "other light source";
break;
};
}
break;
case 0xA001: /* ColorSpace */
if (tag->Type == 3 && tag->Count == 1)
{
switch (*(tag->ShortValues + 0))
{
case 1:
human = "sRGB";
break;
case 0xffff:
human = "Uncalibrated";
break;
};
}
break;
case 0x8827: /* ISOSpeedRatings */
if (tag->Type == 3 && tag->Count == 1)
{
sprintf (dummy, "%u ISO", *(tag->ShortValues + 0));
human = dummy;
}
break;
case 0xA002: /* ExifImageWidth */
case 0xA003: /* ExifImageLength */
if (tag->Type == 3 && tag->Count == 1)
{
sprintf (dummy, "%u pixels", *(tag->ShortValues + 0));
human = dummy;
}
else if (tag->Type == 4 && tag->Count == 1)
{
sprintf (dummy, "%u pixels", *(tag->LongValues + 0));
human = dummy;
}
break;
case 0x829A: /* ExposureTime */
if (tag->Type == 5 && tag->Count == 1)
{
dblval = gaiaExifTagGetRationalValue (tag, 0, &xok);
if (xok)
{
if (dblval < 1.0)
{
dblval = 1.0 / dblval;
sprintf (dummy, "1/%1.0f sec", dblval);
human = dummy;
}
else
{
sprintf (dummy, "%1.0f sec", dblval);
human = dummy;
}
}
}
break;
case 0x9201: /* ShutterSpeedValue */
if (tag->Type == 10 && tag->Count == 1)
{
dblval = gaiaExifTagGetSignedRationalValue (tag, 0, &xok);
if (xok)
{
dblval = exp (dblval * log (2));
if (dblval > 1.0)
dblval = floor (dblval);
if (dblval < 1.0)
{
dblval = math_round (1.0 / dblval);
sprintf (dummy, "%1.0f sec", dblval);
human = dummy;
}
else
{
sprintf (dummy, "1/%1.0f sec", dblval);
human = dummy;
}
}
}
break;
case 0x829D: /* FNumber */
if (tag->Type == 5 && tag->Count == 1)
{
dblval = gaiaExifTagGetRationalValue (tag, 0, &xok);
if (xok)
{
sprintf (dummy, "F %1.1f", dblval);
human = dummy;
}
}
break;
case 0x9202: /* ApertureValue */
case 0x9205: /* MaxApertureValue */
if (tag->Type == 5 && tag->Count == 1)
{
dblval = gaiaExifTagGetRationalValue (tag, 0, &xok);
if (xok)
{
dblval = exp ((dblval * log (2)) / 2.0);
sprintf (dummy, "F %1.1f", dblval);
human = dummy;
}
}
break;
case 0x920A: /* FocalLength */
if (tag->Type == 5 && tag->Count == 1)
{
dblval = gaiaExifTagGetRationalValue (tag, 0, &xok);
if (xok)
{
sprintf (dummy, "%1.1f mm", dblval);
human = dummy;
}
}
break;
case 0xA405: /* FocalLengthIn35mmFilm */
if (tag->Type == 3 && tag->Count == 1)
{
sprintf (dummy, "%u mm", *(tag->ShortValues + 0));
human = dummy;
}
break;
case 0x9204: /* ExposureBiasValue */
if (tag->Type == 10 && tag->Count == 1)
{
dblval = gaiaExifTagGetSignedRationalValue (tag, 0, &xok);
if (xok)
{
sprintf (dummy, "%1.2f EV", dblval);
human = dummy;
}
}
break;
};
l = strlen (human);
if (l > 0)
{
if (len > l)
strcpy (str, human);
else
{
memset (str, '\0', len);
memcpy (str, human, len - 1);
}
*ok = 1;
return;
}
*ok = 0;
}
static int
parse_multi_geom (const unsigned char *blob, int size, int endian,
int endian_arch, int *is_compr)
{
/* testing for a compressed multi-geometry */
int entities;
int type;
int ie;
int offset = 43;
int points;
int rings;
int ib;
int compressed = 0;
int not_compressed = 0;
if (size < offset + 4)
return 0;
entities = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ie = 0; ie < entities; ie++)
{
if (size < offset + 5)
return 0;
type = gaiaImport32 (blob + offset + 1, endian, endian_arch);
offset += 5;
switch (type)
{
case GAIA_POINT:
if (size < offset + 16)
return 0;
offset += 16;
break;
case GAIA_POINTZ:
if (size < offset + 24)
return 0;
offset += 24;
break;
case GAIA_POINTM:
if (size < offset + 24)
return 0;
offset += 24;
break;
case GAIA_POINTZM:
if (size < offset + 32)
return 0;
offset += 32;
break;
case GAIA_LINESTRING:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 16);
not_compressed = 1;
break;
case GAIA_LINESTRINGZ:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 24);
not_compressed = 1;
break;
case GAIA_LINESTRINGM:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 24);
not_compressed = 1;
break;
case GAIA_LINESTRINGZM:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 32);
not_compressed = 1;
break;
case GAIA_POLYGON:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 16);
}
not_compressed = 1;
break;
case GAIA_POLYGONZ:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 24);
}
not_compressed = 1;
break;
case GAIA_POLYGONM:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 24);
}
not_compressed = 1;
break;
case GAIA_POLYGONZM:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 32);
}
not_compressed = 1;
break;
case GAIA_COMPRESSED_LINESTRING:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 8) + 16;
compressed = 1;
break;
case GAIA_COMPRESSED_LINESTRINGZ:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 12) + 24;
compressed = 1;
break;
case GAIA_COMPRESSED_LINESTRINGM:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 16) + 16;
compressed = 1;
break;
case GAIA_COMPRESSED_LINESTRINGZM:
if (size < offset + 4)
return 0;
points = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 20) + 24;
compressed = 1;
break;
case GAIA_COMPRESSED_POLYGON:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 8) + 16;
}
compressed = 1;
break;
case GAIA_COMPRESSED_POLYGONZ:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 12) + 24;
}
compressed = 1;
break;
case GAIA_COMPRESSED_POLYGONM:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 16) + 16;
}
compressed = 1;
break;
case GAIA_COMPRESSED_POLYGONZM:
if (size < offset + 4)
return 0;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (size < offset + 4)
return 0;
points =
gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4 + (points * 20) + 24;
}
compressed = 1;
break;
default:
return 0;
};
}
if (compressed && !not_compressed)
*is_compr = 1;
else
*is_compr = 0;
return 1;
}
GAIAEXIF_DECLARE int
gaiaGuessBlobType (const unsigned char *blob, int size)
{
/* returns the BLOB content type */
int jpeg = 0;
int exif = 0;
int exif_gps = 0;
int geom = 1;
int tiny_point = 1;
gaiaExifTagListPtr exif_list;
gaiaExifTagPtr pT;
unsigned char jpeg1_signature[2];
unsigned char jpeg2_signature[2];
unsigned char jpeg3_signature[4];
unsigned char jfif_signature[4];
unsigned char exif_signature[4];
unsigned char png_signature[8];
unsigned char zip_signature[4];
unsigned char tiff_signature_little[4];
unsigned char tiff_signature_big[4];
unsigned char riff_signature[4];
unsigned char webp_signature[8];
unsigned char jp2_little[12];
unsigned char jp2_big[12];
jpeg1_signature[0] = 0xff;
jpeg1_signature[1] = 0xd8;
jpeg2_signature[0] = 0xff;
jpeg2_signature[1] = 0xd9;
jpeg3_signature[0] = 0xff;
jpeg3_signature[1] = 0xd8;
jpeg3_signature[2] = 0xff;
jpeg3_signature[3] = 0xe0;
jfif_signature[0] = 0x4a;
jfif_signature[1] = 0x46;
jfif_signature[2] = 0x49;
jfif_signature[3] = 0x46;
exif_signature[0] = 0x45;
exif_signature[1] = 0x78;
exif_signature[2] = 0x69;
exif_signature[3] = 0x66;
png_signature[0] = 0x89;
png_signature[1] = 0x50;
png_signature[2] = 0x4e;
png_signature[3] = 0x47;
png_signature[4] = 0x0d;
png_signature[5] = 0x0a;
png_signature[6] = 0x1a;
png_signature[7] = 0x0a;
zip_signature[0] = 0x50;
zip_signature[1] = 0x4b;
zip_signature[2] = 0x03;
zip_signature[3] = 0x04;
tiff_signature_little[0] = 'I';
tiff_signature_little[1] = 'I';
tiff_signature_little[2] = 0x2a;
tiff_signature_little[3] = 0x00;
tiff_signature_big[0] = 'M';
tiff_signature_big[1] = 'M';
tiff_signature_big[2] = 0x00;
tiff_signature_big[3] = 0x2a;
riff_signature[0] = 'R';
riff_signature[1] = 'I';
riff_signature[2] = 'F';
riff_signature[3] = 'F';
webp_signature[0] = 'W';
webp_signature[1] = 'E';
webp_signature[2] = 'B';
webp_signature[3] = 'P';
webp_signature[4] = 'V';
webp_signature[5] = 'P';
webp_signature[6] = '8';
webp_signature[7] = ' ';
jp2_big[0] = 0x00;
jp2_big[1] = 0x00;
jp2_big[2] = 0x00;
jp2_big[3] = 0x0C;
jp2_big[4] = 0x6A;
jp2_big[5] = 0x50;
jp2_big[6] = 0x20;
jp2_big[7] = 0x20;
jp2_big[8] = 0x0D;
jp2_big[9] = 0x0A;
jp2_big[10] = 0x87;
jp2_big[11] = 0x0A;
jp2_little[0] = 0x00;
jp2_little[1] = 0x00;
jp2_little[2] = 0x0c;
jp2_little[3] = 0x00;
jp2_little[4] = 0x50;
jp2_little[5] = 0x6a;
jp2_little[6] = 0x20;
jp2_little[7] = 0x20;
jp2_little[8] = 0x0a;
jp2_little[9] = 0x0d;
jp2_little[10] = 0x0a;
jp2_little[11] = 0x87;
if (size < 1 || !blob)
return GAIA_HEX_BLOB;
if (size > 4)
{
if (memcmp (blob, tiff_signature_big, 4) == 0)
return GAIA_TIFF_BLOB;
if (memcmp (blob, tiff_signature_little, 4) == 0)
return GAIA_TIFF_BLOB;
}
if (size > 5)
{
if (strncmp ((char *) blob, "%PDF-", 5) == 0)
return GAIA_PDF_BLOB;
}
if (size > 4)
{
if (memcmp (blob, zip_signature, 4) == 0)
return GAIA_ZIP_BLOB;
}
if (size > 6)
{
if (strncmp ((char *) blob, "GIF87a", 6) == 0
|| strncmp ((char *) blob, "GIF89a", 6) == 0)
return GAIA_GIF_BLOB;
}
if (size > 8)
{
if (memcmp (blob, png_signature, 8) == 0)
return GAIA_PNG_BLOB;
}
if (size > 12)
{
if (memcmp (blob, jp2_big, 12) == 0)
return GAIA_JP2_BLOB;
if (memcmp (blob, jp2_little, 12) == 0)
return GAIA_JP2_BLOB;
}
if (size > 4)
{
if (memcmp (blob, jpeg1_signature, 2) == 0
&& memcmp (blob + size - 2, jpeg2_signature, 2) == 0)
jpeg = 1; /* this one is the standard JPEG signature */
if (memcmp (blob, jpeg3_signature, 4) == 0)
jpeg = 1; /* another common JPEG signature */
}
if (size > 10)
{
if (memcmp (blob + 6, jfif_signature, 4) == 0)
jpeg = 1; /* standard JFIF signature */
if (memcmp (blob + 6, exif_signature, 4) == 0)
jpeg = 1; /* standard EXIF signature */
}
if (jpeg)
{
exif_list = gaiaGetExifTags (blob, size);
if (exif_list)
{
exif = 1;
pT = exif_list->First;
while (pT)
{
if (pT->Gps)
{
exif_gps = 1;
break;
}
pT = pT->Next;
}
gaiaExifTagsFree (exif_list);
}
}
if (jpeg && exif && exif_gps)
return GAIA_EXIF_GPS_BLOB;
if (jpeg && exif)
return GAIA_EXIF_BLOB;
if (jpeg)
return GAIA_JPEG_BLOB;
if (size > 16)
{
if ((memcmp (blob, riff_signature, 4) == 0) &&
(memcmp (blob + 8, webp_signature, 8) == 0))
return GAIA_WEBP_BLOB;
}
/* testing for GEOMETRY */
if (size < 45)
geom = 0;
else
{
if (*(blob + 0) != GAIA_MARK_START)
geom = 0;
if (*(blob + 1) == GAIA_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_BIG_ENDIAN)
;
else
geom = 0;
if (*(blob + (size - 1)) != GAIA_MARK_END)
geom = 0;
if (*(blob + 38) != GAIA_MARK_MBR)
geom = 0;
}
if (geom)
{
int little_endian;
int endian_arch = gaiaEndianArch ();
int gtype;
int is_compr;
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
goto not_a_valid_geom;
gtype = gaiaImport32 (blob + 39, little_endian, endian_arch);
switch (gtype)
{
case GAIA_COMPRESSED_LINESTRING:
case GAIA_COMPRESSED_LINESTRINGZ:
case GAIA_COMPRESSED_LINESTRINGM:
case GAIA_COMPRESSED_LINESTRINGZM:
case GAIA_COMPRESSED_POLYGON:
case GAIA_COMPRESSED_POLYGONZ:
case GAIA_COMPRESSED_POLYGONM:
case GAIA_COMPRESSED_POLYGONZM:
return GAIA_COMPRESSED_GEOMETRY_BLOB;
case GAIA_MULTILINESTRING:
case GAIA_MULTILINESTRINGZ:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTILINESTRINGZM:
case GAIA_MULTIPOLYGON:
case GAIA_MULTIPOLYGONZ:
case GAIA_MULTIPOLYGONM:
case GAIA_MULTIPOLYGONZM:
case GAIA_GEOMETRYCOLLECTION:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_GEOMETRYCOLLECTIONZM:
if (!parse_multi_geom
(blob, size, little_endian, endian_arch, &is_compr))
goto not_a_valid_geom;
if (is_compr)
return GAIA_COMPRESSED_GEOMETRY_BLOB;
else
return GAIA_GEOMETRY_BLOB;
default:
return GAIA_GEOMETRY_BLOB;
}
}
not_a_valid_geom:
/* testing for TinyPoint */
if (size < 24)
tiny_point = 0;
else
{
if (*(blob + 0) != GAIA_MARK_START)
tiny_point = 0;
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
;
else
tiny_point = 0;
if (*(blob + 6) == GAIA_TINYPOINT_XY
|| *(blob + 6) == GAIA_TINYPOINT_XYZ
|| *(blob + 6) == GAIA_TINYPOINT_XYM
|| *(blob + 6) == GAIA_TINYPOINT_XYZM)
;
else
tiny_point = 0;
if (*(blob + (size - 1)) != GAIA_MARK_END)
tiny_point = 0;
}
if (tiny_point)
return GAIA_TINYPOINT_BLOB;
#ifdef ENABLE_LIBXML2 /* LIBXML2 enabled: supporting XML documents */
if (gaiaIsValidXmlBlob (blob, size))
return GAIA_XML_BLOB;
#endif /* end LIBXML2: supporting XML documents */
#ifdef ENABLE_GEOPACKAGE /* GEOPACKAGE enabled: supporting GPKG geometries */
if (gaiaIsValidGPB (blob, size))
return GAIA_GPB_BLOB;
#endif /* end GEOPACKAGE: supporting GPKG geometries */
return GAIA_HEX_BLOB;
}
GAIAEXIF_DECLARE int
gaiaGetGpsCoords (const unsigned char *blob, int size, double *longitude,
double *latitude)
{
/* returns the ExifGps coords, if they exists */
gaiaExifTagListPtr exif_list;
gaiaExifTagPtr pT;
char lat_ref = '\0';
char long_ref = '\0';
double lat_degs = -DBL_MAX;
double lat_mins = -DBL_MAX;
double lat_secs = -DBL_MAX;
double long_degs = -DBL_MAX;
double long_mins = -DBL_MAX;
double long_secs = -DBL_MAX;
double dblval;
double sign;
int ok;
if (size < 1 || !blob)
return 0;
exif_list = gaiaGetExifTags (blob, size);
if (exif_list)
{
pT = exif_list->First;
while (pT)
{
if (pT->Gps && pT->TagId == 0x01)
{
/* ok, this one is the GPSLatitudeRef tag */
if (pT->Type == 2)
lat_ref = *(pT->StringValue);
}
if (pT->Gps && pT->TagId == 0x03)
{
/* ok, this one is the GPSLongitudeRef tag */
if (pT->Type == 2)
long_ref = *(pT->StringValue);
}
if (pT->Gps && pT->TagId == 0x02)
{
/* ok, this one is the GPSLatitude tag */
if (pT->Type == 5 && pT->Count == 3)
{
dblval = gaiaExifTagGetRationalValue (pT, 0, &ok);
if (ok)
lat_degs = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 1, &ok);
if (ok)
lat_mins = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 2, &ok);
if (ok)
lat_secs = dblval;
}
}
if (pT->Gps && pT->TagId == 0x04)
{
/* ok, this one is the GPSLongitude tag */
if (pT->Type == 5 && pT->Count == 3)
{
dblval = gaiaExifTagGetRationalValue (pT, 0, &ok);
if (ok)
long_degs = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 1, &ok);
if (ok)
long_mins = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 2, &ok);
if (ok)
long_secs = dblval;
}
}
pT = pT->Next;
}
gaiaExifTagsFree (exif_list);
if ((lat_ref == 'N' || lat_ref == 'S' || long_ref == 'E'
|| long_ref == 'W') && lat_degs != -DBL_MAX
&& lat_mins != -DBL_MAX && lat_secs != -DBL_MAX
&& long_degs != -DBL_MAX && long_mins != -DBL_MAX
&& long_secs != -DBL_MAX)
{
if (lat_ref == 'S')
sign = -1.0;
else
sign = 1.0;
lat_degs = math_round (lat_degs * 1000000.0);
lat_mins = math_round (lat_mins * 1000000.0);
lat_secs = math_round (lat_secs * 1000000.0);
dblval =
math_round (lat_degs + (lat_mins / 60.0) +
(lat_secs / 3600.0)) * (sign / 1000000.0);
*latitude = dblval;
if (long_ref == 'W')
sign = -1.0;
else
sign = 1.0;
long_degs = math_round (long_degs * 1000000.0);
long_mins = math_round (long_mins * 1000000.0);
long_secs = math_round (long_secs * 1000000.0);
dblval =
math_round (long_degs + (long_mins / 60.0) +
(long_secs / 3600.0)) * (sign / 1000000.0);
*longitude = dblval;
return 1;
}
}
return 0;
}
GAIAEXIF_DECLARE int
gaiaGetGpsLatLong (const unsigned char *blob, int size, char *latlong,
int ll_size)
{
/* returns the ExifGps Latitude and Longitude, if they exists */
gaiaExifTagListPtr exif_list;
gaiaExifTagPtr pT;
char lat_ref = '\0';
char long_ref = '\0';
double lat_degs = -DBL_MAX;
double lat_mins = -DBL_MAX;
double lat_secs = -DBL_MAX;
double long_degs = -DBL_MAX;
double long_mins = -DBL_MAX;
double long_secs = -DBL_MAX;
double dblval;
int ok;
char ll[1024];
int len;
*latlong = '\0';
if (size < 1 || !blob)
return 0;
exif_list = gaiaGetExifTags (blob, size);
if (exif_list)
{
pT = exif_list->First;
while (pT)
{
if (pT->Gps && pT->TagId == 0x01)
{
/* ok, this one is the GPSLatitudeRef tag */
if (pT->Type == 2)
lat_ref = *(pT->StringValue);
}
if (pT->Gps && pT->TagId == 0x03)
{
/* ok, this one is the GPSLongitudeRef tag */
if (pT->Type == 2)
long_ref = *(pT->StringValue);
}
if (pT->Gps && pT->TagId == 0x02)
{
/* ok, this one is the GPSLatitude tag */
if (pT->Type == 5 && pT->Count == 3)
{
dblval = gaiaExifTagGetRationalValue (pT, 0, &ok);
if (ok)
lat_degs = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 1, &ok);
if (ok)
lat_mins = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 2, &ok);
if (ok)
lat_secs = dblval;
}
}
if (pT->Gps && pT->TagId == 0x04)
{
/* ok, this one is the GPSLongitude tag */
if (pT->Type == 5 && pT->Count == 3)
{
dblval = gaiaExifTagGetRationalValue (pT, 0, &ok);
if (ok)
long_degs = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 1, &ok);
if (ok)
long_mins = dblval;
dblval = gaiaExifTagGetRationalValue (pT, 2, &ok);
if (ok)
long_secs = dblval;
}
}
pT = pT->Next;
}
gaiaExifTagsFree (exif_list);
if ((lat_ref == 'N' || lat_ref == 'S' || long_ref == 'E'
|| long_ref == 'W') && lat_degs != -DBL_MAX
&& lat_mins != -DBL_MAX && lat_secs != -DBL_MAX
&& long_degs != -DBL_MAX && long_mins != -DBL_MAX
&& long_secs != -DBL_MAX)
{
int long_d = long_degs;
int long_m = long_mins;
int long_s = long_secs;
int lat_d = lat_degs;
int lat_m = lat_mins;
int lat_s = lat_secs;
sprintf (ll, "%02d°%02d′%02d″%c %03d°%02d′%02d″%c",
lat_d, lat_m, lat_s, lat_ref, long_d, long_m, long_s,
long_ref);
len = strlen (ll);
if (len < ll_size)
strcpy (latlong, ll);
else
{
memcpy (latlong, ll, ll_size - 1);
latlong[ll_size] = '\0';
}
return 1;
}
}
return 0;
}
libspatialite-5.1.0/src/gaiageo/ 0000755 0001750 0001750 00000000000 14463127115 013533 5 0000000 0000000 libspatialite-5.1.0/src/gaiageo/Makefile.am 0000644 0001750 0001750 00000002075 14463127014 015511 0000000 0000000
SUBDIRS = flex lemon
AM_CPPFLAGS = -I$(top_srcdir)/src/headers
AM_CPPFLAGS += @CFLAGS@ @CPPFLAGS@ @GEOS_CFLAGS@ @LIBXML2_CFLAGS@
noinst_LTLIBRARIES = libgaiageo.la gaiageo.la
GAIAGEO_COMMON_SOURCES = gg_advanced.c \
gg_endian.c \
gg_geodesic.c \
gg_geometries.c \
gg_geoscvt.c \
gg_relations.c \
gg_relations_ext.c \
gg_rttopo.c \
gg_extras.c \
gg_shape.c \
gg_transform.c \
gg_wkb.c \
gg_wkt.c \
gg_vanuatu.c \
gg_ewkt.c \
gg_geoJSON.c \
gg_kml.c \
gg_gml.c \
gg_voronoj.c \
gg_xml.c \
gg_matrix.c
libgaiageo_la_SOURCES = $(GAIAGEO_COMMON_SOURCES)
gaiageo_la_SOURCES = $(GAIAGEO_COMMON_SOURCES)
gaiageo_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I.
gaiageo_la_CPPFLAGS += @CFLAGS@ @CPPFLAGS@ @GEOS_CFLAGS@ @LIBXML2_CFLAGS@
gaiageo_la_CPPFLAGS += -DLOADABLE_EXTENSION
gaiageo_la_LDFLAGS = -module
gaiageo_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
EXTRA_DIST = Ewkt.h Ewkt.c lex.Ewkt.c \
geoJSON.h geoJSON.c lex.GeoJson.c \
Gml.h Gml.c lex.Gml.c \
Kml.h Kml.c lex.Kml.c \
vanuatuWkt.h vanuatuWkt.c lex.VanuatuWkt.c
libspatialite-5.1.0/src/gaiageo/Makefile.in 0000644 0001750 0001750 00000156672 14463127014 015537 0000000 0000000 # Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/gaiageo
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./fakeconfig.h \
$(top_builddir)/./config.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig.h \
$(top_builddir)/./config-msvc.h \
$(top_builddir)/./src/headers/spatialite/gaiaconfig-msvc.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
gaiageo_la_LIBADD =
am__objects_1 = gaiageo_la-gg_advanced.lo gaiageo_la-gg_endian.lo \
gaiageo_la-gg_geodesic.lo gaiageo_la-gg_geometries.lo \
gaiageo_la-gg_geoscvt.lo gaiageo_la-gg_relations.lo \
gaiageo_la-gg_relations_ext.lo gaiageo_la-gg_rttopo.lo \
gaiageo_la-gg_extras.lo gaiageo_la-gg_shape.lo \
gaiageo_la-gg_transform.lo gaiageo_la-gg_wkb.lo \
gaiageo_la-gg_wkt.lo gaiageo_la-gg_vanuatu.lo \
gaiageo_la-gg_ewkt.lo gaiageo_la-gg_geoJSON.lo \
gaiageo_la-gg_kml.lo gaiageo_la-gg_gml.lo \
gaiageo_la-gg_voronoj.lo gaiageo_la-gg_xml.lo \
gaiageo_la-gg_matrix.lo
am_gaiageo_la_OBJECTS = $(am__objects_1)
gaiageo_la_OBJECTS = $(am_gaiageo_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
gaiageo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(gaiageo_la_LDFLAGS) $(LDFLAGS) -o $@
libgaiageo_la_LIBADD =
am__objects_2 = gg_advanced.lo gg_endian.lo gg_geodesic.lo \
gg_geometries.lo gg_geoscvt.lo gg_relations.lo \
gg_relations_ext.lo gg_rttopo.lo gg_extras.lo gg_shape.lo \
gg_transform.lo gg_wkb.lo gg_wkt.lo gg_vanuatu.lo gg_ewkt.lo \
gg_geoJSON.lo gg_kml.lo gg_gml.lo gg_voronoj.lo gg_xml.lo \
gg_matrix.lo
am_libgaiageo_la_OBJECTS = $(am__objects_2)
libgaiageo_la_OBJECTS = $(am_libgaiageo_la_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/. -I$(top_builddir)/./src/headers/spatialite
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/gaiageo_la-gg_advanced.Plo \
./$(DEPDIR)/gaiageo_la-gg_endian.Plo \
./$(DEPDIR)/gaiageo_la-gg_ewkt.Plo \
./$(DEPDIR)/gaiageo_la-gg_extras.Plo \
./$(DEPDIR)/gaiageo_la-gg_geoJSON.Plo \
./$(DEPDIR)/gaiageo_la-gg_geodesic.Plo \
./$(DEPDIR)/gaiageo_la-gg_geometries.Plo \
./$(DEPDIR)/gaiageo_la-gg_geoscvt.Plo \
./$(DEPDIR)/gaiageo_la-gg_gml.Plo \
./$(DEPDIR)/gaiageo_la-gg_kml.Plo \
./$(DEPDIR)/gaiageo_la-gg_matrix.Plo \
./$(DEPDIR)/gaiageo_la-gg_relations.Plo \
./$(DEPDIR)/gaiageo_la-gg_relations_ext.Plo \
./$(DEPDIR)/gaiageo_la-gg_rttopo.Plo \
./$(DEPDIR)/gaiageo_la-gg_shape.Plo \
./$(DEPDIR)/gaiageo_la-gg_transform.Plo \
./$(DEPDIR)/gaiageo_la-gg_vanuatu.Plo \
./$(DEPDIR)/gaiageo_la-gg_voronoj.Plo \
./$(DEPDIR)/gaiageo_la-gg_wkb.Plo \
./$(DEPDIR)/gaiageo_la-gg_wkt.Plo \
./$(DEPDIR)/gaiageo_la-gg_xml.Plo ./$(DEPDIR)/gg_advanced.Plo \
./$(DEPDIR)/gg_endian.Plo ./$(DEPDIR)/gg_ewkt.Plo \
./$(DEPDIR)/gg_extras.Plo ./$(DEPDIR)/gg_geoJSON.Plo \
./$(DEPDIR)/gg_geodesic.Plo ./$(DEPDIR)/gg_geometries.Plo \
./$(DEPDIR)/gg_geoscvt.Plo ./$(DEPDIR)/gg_gml.Plo \
./$(DEPDIR)/gg_kml.Plo ./$(DEPDIR)/gg_matrix.Plo \
./$(DEPDIR)/gg_relations.Plo ./$(DEPDIR)/gg_relations_ext.Plo \
./$(DEPDIR)/gg_rttopo.Plo ./$(DEPDIR)/gg_shape.Plo \
./$(DEPDIR)/gg_transform.Plo ./$(DEPDIR)/gg_vanuatu.Plo \
./$(DEPDIR)/gg_voronoj.Plo ./$(DEPDIR)/gg_wkb.Plo \
./$(DEPDIR)/gg_wkt.Plo ./$(DEPDIR)/gg_xml.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(gaiageo_la_SOURCES) $(libgaiageo_la_SOURCES)
DIST_SOURCES = $(gaiageo_la_SOURCES) $(libgaiageo_la_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir distdir-am
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GEOSCONFIG = @GEOSCONFIG@
GEOS_CFLAGS = @GEOS_CFLAGS@
GEOS_LDFLAGS = @GEOS_LDFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = flex lemon
AM_CPPFLAGS = -I$(top_srcdir)/src/headers @CFLAGS@ @CPPFLAGS@ \
@GEOS_CFLAGS@ @LIBXML2_CFLAGS@ $(am__empty)
noinst_LTLIBRARIES = libgaiageo.la gaiageo.la
GAIAGEO_COMMON_SOURCES = gg_advanced.c \
gg_endian.c \
gg_geodesic.c \
gg_geometries.c \
gg_geoscvt.c \
gg_relations.c \
gg_relations_ext.c \
gg_rttopo.c \
gg_extras.c \
gg_shape.c \
gg_transform.c \
gg_wkb.c \
gg_wkt.c \
gg_vanuatu.c \
gg_ewkt.c \
gg_geoJSON.c \
gg_kml.c \
gg_gml.c \
gg_voronoj.c \
gg_xml.c \
gg_matrix.c
libgaiageo_la_SOURCES = $(GAIAGEO_COMMON_SOURCES)
gaiageo_la_SOURCES = $(GAIAGEO_COMMON_SOURCES)
gaiageo_la_CPPFLAGS = -I$(top_srcdir)/src/headers -I. @CFLAGS@ \
@CPPFLAGS@ @GEOS_CFLAGS@ @LIBXML2_CFLAGS@ -DLOADABLE_EXTENSION
gaiageo_la_LDFLAGS = -module
gaiageo_la_LIBTOOLFLAGS = --tag=disable-static
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
EXTRA_DIST = Ewkt.h Ewkt.c lex.Ewkt.c \
geoJSON.h geoJSON.c lex.GeoJson.c \
Gml.h Gml.c lex.Gml.c \
Kml.h Kml.c lex.Kml.c \
vanuatuWkt.h vanuatuWkt.c lex.VanuatuWkt.c
all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/gaiageo/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/gaiageo/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
gaiageo.la: $(gaiageo_la_OBJECTS) $(gaiageo_la_DEPENDENCIES) $(EXTRA_gaiageo_la_DEPENDENCIES)
$(AM_V_CCLD)$(gaiageo_la_LINK) $(gaiageo_la_OBJECTS) $(gaiageo_la_LIBADD) $(LIBS)
libgaiageo.la: $(libgaiageo_la_OBJECTS) $(libgaiageo_la_DEPENDENCIES) $(EXTRA_libgaiageo_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libgaiageo_la_OBJECTS) $(libgaiageo_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_advanced.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_endian.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_ewkt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_extras.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_geoJSON.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_geodesic.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_geometries.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_geoscvt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_gml.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_kml.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_matrix.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_relations.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_relations_ext.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_rttopo.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_shape.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_transform.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_vanuatu.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_voronoj.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_wkb.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_wkt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaiageo_la-gg_xml.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_advanced.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_endian.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_ewkt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_extras.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_geoJSON.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_geodesic.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_geometries.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_geoscvt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_gml.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_kml.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_matrix.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_relations.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_relations_ext.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_rttopo.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_shape.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_transform.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_vanuatu.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_voronoj.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_wkb.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_wkt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_xml.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
gaiageo_la-gg_advanced.lo: gg_advanced.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_advanced.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_advanced.Tpo -c -o gaiageo_la-gg_advanced.lo `test -f 'gg_advanced.c' || echo '$(srcdir)/'`gg_advanced.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_advanced.Tpo $(DEPDIR)/gaiageo_la-gg_advanced.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_advanced.c' object='gaiageo_la-gg_advanced.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_advanced.lo `test -f 'gg_advanced.c' || echo '$(srcdir)/'`gg_advanced.c
gaiageo_la-gg_endian.lo: gg_endian.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_endian.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_endian.Tpo -c -o gaiageo_la-gg_endian.lo `test -f 'gg_endian.c' || echo '$(srcdir)/'`gg_endian.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_endian.Tpo $(DEPDIR)/gaiageo_la-gg_endian.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_endian.c' object='gaiageo_la-gg_endian.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_endian.lo `test -f 'gg_endian.c' || echo '$(srcdir)/'`gg_endian.c
gaiageo_la-gg_geodesic.lo: gg_geodesic.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_geodesic.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_geodesic.Tpo -c -o gaiageo_la-gg_geodesic.lo `test -f 'gg_geodesic.c' || echo '$(srcdir)/'`gg_geodesic.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_geodesic.Tpo $(DEPDIR)/gaiageo_la-gg_geodesic.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_geodesic.c' object='gaiageo_la-gg_geodesic.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_geodesic.lo `test -f 'gg_geodesic.c' || echo '$(srcdir)/'`gg_geodesic.c
gaiageo_la-gg_geometries.lo: gg_geometries.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_geometries.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_geometries.Tpo -c -o gaiageo_la-gg_geometries.lo `test -f 'gg_geometries.c' || echo '$(srcdir)/'`gg_geometries.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_geometries.Tpo $(DEPDIR)/gaiageo_la-gg_geometries.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_geometries.c' object='gaiageo_la-gg_geometries.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_geometries.lo `test -f 'gg_geometries.c' || echo '$(srcdir)/'`gg_geometries.c
gaiageo_la-gg_geoscvt.lo: gg_geoscvt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_geoscvt.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_geoscvt.Tpo -c -o gaiageo_la-gg_geoscvt.lo `test -f 'gg_geoscvt.c' || echo '$(srcdir)/'`gg_geoscvt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_geoscvt.Tpo $(DEPDIR)/gaiageo_la-gg_geoscvt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_geoscvt.c' object='gaiageo_la-gg_geoscvt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_geoscvt.lo `test -f 'gg_geoscvt.c' || echo '$(srcdir)/'`gg_geoscvt.c
gaiageo_la-gg_relations.lo: gg_relations.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_relations.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_relations.Tpo -c -o gaiageo_la-gg_relations.lo `test -f 'gg_relations.c' || echo '$(srcdir)/'`gg_relations.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_relations.Tpo $(DEPDIR)/gaiageo_la-gg_relations.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_relations.c' object='gaiageo_la-gg_relations.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_relations.lo `test -f 'gg_relations.c' || echo '$(srcdir)/'`gg_relations.c
gaiageo_la-gg_relations_ext.lo: gg_relations_ext.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_relations_ext.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_relations_ext.Tpo -c -o gaiageo_la-gg_relations_ext.lo `test -f 'gg_relations_ext.c' || echo '$(srcdir)/'`gg_relations_ext.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_relations_ext.Tpo $(DEPDIR)/gaiageo_la-gg_relations_ext.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_relations_ext.c' object='gaiageo_la-gg_relations_ext.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_relations_ext.lo `test -f 'gg_relations_ext.c' || echo '$(srcdir)/'`gg_relations_ext.c
gaiageo_la-gg_rttopo.lo: gg_rttopo.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_rttopo.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_rttopo.Tpo -c -o gaiageo_la-gg_rttopo.lo `test -f 'gg_rttopo.c' || echo '$(srcdir)/'`gg_rttopo.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_rttopo.Tpo $(DEPDIR)/gaiageo_la-gg_rttopo.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_rttopo.c' object='gaiageo_la-gg_rttopo.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_rttopo.lo `test -f 'gg_rttopo.c' || echo '$(srcdir)/'`gg_rttopo.c
gaiageo_la-gg_extras.lo: gg_extras.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_extras.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_extras.Tpo -c -o gaiageo_la-gg_extras.lo `test -f 'gg_extras.c' || echo '$(srcdir)/'`gg_extras.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_extras.Tpo $(DEPDIR)/gaiageo_la-gg_extras.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_extras.c' object='gaiageo_la-gg_extras.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_extras.lo `test -f 'gg_extras.c' || echo '$(srcdir)/'`gg_extras.c
gaiageo_la-gg_shape.lo: gg_shape.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_shape.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_shape.Tpo -c -o gaiageo_la-gg_shape.lo `test -f 'gg_shape.c' || echo '$(srcdir)/'`gg_shape.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_shape.Tpo $(DEPDIR)/gaiageo_la-gg_shape.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_shape.c' object='gaiageo_la-gg_shape.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_shape.lo `test -f 'gg_shape.c' || echo '$(srcdir)/'`gg_shape.c
gaiageo_la-gg_transform.lo: gg_transform.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_transform.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_transform.Tpo -c -o gaiageo_la-gg_transform.lo `test -f 'gg_transform.c' || echo '$(srcdir)/'`gg_transform.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_transform.Tpo $(DEPDIR)/gaiageo_la-gg_transform.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_transform.c' object='gaiageo_la-gg_transform.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_transform.lo `test -f 'gg_transform.c' || echo '$(srcdir)/'`gg_transform.c
gaiageo_la-gg_wkb.lo: gg_wkb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_wkb.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_wkb.Tpo -c -o gaiageo_la-gg_wkb.lo `test -f 'gg_wkb.c' || echo '$(srcdir)/'`gg_wkb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_wkb.Tpo $(DEPDIR)/gaiageo_la-gg_wkb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_wkb.c' object='gaiageo_la-gg_wkb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_wkb.lo `test -f 'gg_wkb.c' || echo '$(srcdir)/'`gg_wkb.c
gaiageo_la-gg_wkt.lo: gg_wkt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_wkt.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_wkt.Tpo -c -o gaiageo_la-gg_wkt.lo `test -f 'gg_wkt.c' || echo '$(srcdir)/'`gg_wkt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_wkt.Tpo $(DEPDIR)/gaiageo_la-gg_wkt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_wkt.c' object='gaiageo_la-gg_wkt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_wkt.lo `test -f 'gg_wkt.c' || echo '$(srcdir)/'`gg_wkt.c
gaiageo_la-gg_vanuatu.lo: gg_vanuatu.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_vanuatu.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_vanuatu.Tpo -c -o gaiageo_la-gg_vanuatu.lo `test -f 'gg_vanuatu.c' || echo '$(srcdir)/'`gg_vanuatu.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_vanuatu.Tpo $(DEPDIR)/gaiageo_la-gg_vanuatu.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_vanuatu.c' object='gaiageo_la-gg_vanuatu.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_vanuatu.lo `test -f 'gg_vanuatu.c' || echo '$(srcdir)/'`gg_vanuatu.c
gaiageo_la-gg_ewkt.lo: gg_ewkt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_ewkt.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_ewkt.Tpo -c -o gaiageo_la-gg_ewkt.lo `test -f 'gg_ewkt.c' || echo '$(srcdir)/'`gg_ewkt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_ewkt.Tpo $(DEPDIR)/gaiageo_la-gg_ewkt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_ewkt.c' object='gaiageo_la-gg_ewkt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_ewkt.lo `test -f 'gg_ewkt.c' || echo '$(srcdir)/'`gg_ewkt.c
gaiageo_la-gg_geoJSON.lo: gg_geoJSON.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_geoJSON.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_geoJSON.Tpo -c -o gaiageo_la-gg_geoJSON.lo `test -f 'gg_geoJSON.c' || echo '$(srcdir)/'`gg_geoJSON.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_geoJSON.Tpo $(DEPDIR)/gaiageo_la-gg_geoJSON.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_geoJSON.c' object='gaiageo_la-gg_geoJSON.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_geoJSON.lo `test -f 'gg_geoJSON.c' || echo '$(srcdir)/'`gg_geoJSON.c
gaiageo_la-gg_kml.lo: gg_kml.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_kml.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_kml.Tpo -c -o gaiageo_la-gg_kml.lo `test -f 'gg_kml.c' || echo '$(srcdir)/'`gg_kml.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_kml.Tpo $(DEPDIR)/gaiageo_la-gg_kml.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_kml.c' object='gaiageo_la-gg_kml.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_kml.lo `test -f 'gg_kml.c' || echo '$(srcdir)/'`gg_kml.c
gaiageo_la-gg_gml.lo: gg_gml.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_gml.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_gml.Tpo -c -o gaiageo_la-gg_gml.lo `test -f 'gg_gml.c' || echo '$(srcdir)/'`gg_gml.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_gml.Tpo $(DEPDIR)/gaiageo_la-gg_gml.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_gml.c' object='gaiageo_la-gg_gml.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_gml.lo `test -f 'gg_gml.c' || echo '$(srcdir)/'`gg_gml.c
gaiageo_la-gg_voronoj.lo: gg_voronoj.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_voronoj.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_voronoj.Tpo -c -o gaiageo_la-gg_voronoj.lo `test -f 'gg_voronoj.c' || echo '$(srcdir)/'`gg_voronoj.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_voronoj.Tpo $(DEPDIR)/gaiageo_la-gg_voronoj.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_voronoj.c' object='gaiageo_la-gg_voronoj.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_voronoj.lo `test -f 'gg_voronoj.c' || echo '$(srcdir)/'`gg_voronoj.c
gaiageo_la-gg_xml.lo: gg_xml.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_xml.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_xml.Tpo -c -o gaiageo_la-gg_xml.lo `test -f 'gg_xml.c' || echo '$(srcdir)/'`gg_xml.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_xml.Tpo $(DEPDIR)/gaiageo_la-gg_xml.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_xml.c' object='gaiageo_la-gg_xml.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_xml.lo `test -f 'gg_xml.c' || echo '$(srcdir)/'`gg_xml.c
gaiageo_la-gg_matrix.lo: gg_matrix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gaiageo_la-gg_matrix.lo -MD -MP -MF $(DEPDIR)/gaiageo_la-gg_matrix.Tpo -c -o gaiageo_la-gg_matrix.lo `test -f 'gg_matrix.c' || echo '$(srcdir)/'`gg_matrix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gaiageo_la-gg_matrix.Tpo $(DEPDIR)/gaiageo_la-gg_matrix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gg_matrix.c' object='gaiageo_la-gg_matrix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(gaiageo_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gaiageo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gaiageo_la-gg_matrix.lo `test -f 'gg_matrix.c' || echo '$(srcdir)/'`gg_matrix.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-recursive
-rm -f ./$(DEPDIR)/gaiageo_la-gg_advanced.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_endian.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_ewkt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_extras.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geoJSON.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geodesic.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geometries.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geoscvt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_gml.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_kml.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_matrix.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_relations.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_relations_ext.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_rttopo.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_shape.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_transform.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_vanuatu.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_voronoj.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_wkb.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_wkt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_xml.Plo
-rm -f ./$(DEPDIR)/gg_advanced.Plo
-rm -f ./$(DEPDIR)/gg_endian.Plo
-rm -f ./$(DEPDIR)/gg_ewkt.Plo
-rm -f ./$(DEPDIR)/gg_extras.Plo
-rm -f ./$(DEPDIR)/gg_geoJSON.Plo
-rm -f ./$(DEPDIR)/gg_geodesic.Plo
-rm -f ./$(DEPDIR)/gg_geometries.Plo
-rm -f ./$(DEPDIR)/gg_geoscvt.Plo
-rm -f ./$(DEPDIR)/gg_gml.Plo
-rm -f ./$(DEPDIR)/gg_kml.Plo
-rm -f ./$(DEPDIR)/gg_matrix.Plo
-rm -f ./$(DEPDIR)/gg_relations.Plo
-rm -f ./$(DEPDIR)/gg_relations_ext.Plo
-rm -f ./$(DEPDIR)/gg_rttopo.Plo
-rm -f ./$(DEPDIR)/gg_shape.Plo
-rm -f ./$(DEPDIR)/gg_transform.Plo
-rm -f ./$(DEPDIR)/gg_vanuatu.Plo
-rm -f ./$(DEPDIR)/gg_voronoj.Plo
-rm -f ./$(DEPDIR)/gg_wkb.Plo
-rm -f ./$(DEPDIR)/gg_wkt.Plo
-rm -f ./$(DEPDIR)/gg_xml.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f ./$(DEPDIR)/gaiageo_la-gg_advanced.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_endian.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_ewkt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_extras.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geoJSON.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geodesic.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geometries.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_geoscvt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_gml.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_kml.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_matrix.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_relations.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_relations_ext.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_rttopo.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_shape.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_transform.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_vanuatu.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_voronoj.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_wkb.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_wkt.Plo
-rm -f ./$(DEPDIR)/gaiageo_la-gg_xml.Plo
-rm -f ./$(DEPDIR)/gg_advanced.Plo
-rm -f ./$(DEPDIR)/gg_endian.Plo
-rm -f ./$(DEPDIR)/gg_ewkt.Plo
-rm -f ./$(DEPDIR)/gg_extras.Plo
-rm -f ./$(DEPDIR)/gg_geoJSON.Plo
-rm -f ./$(DEPDIR)/gg_geodesic.Plo
-rm -f ./$(DEPDIR)/gg_geometries.Plo
-rm -f ./$(DEPDIR)/gg_geoscvt.Plo
-rm -f ./$(DEPDIR)/gg_gml.Plo
-rm -f ./$(DEPDIR)/gg_kml.Plo
-rm -f ./$(DEPDIR)/gg_matrix.Plo
-rm -f ./$(DEPDIR)/gg_relations.Plo
-rm -f ./$(DEPDIR)/gg_relations_ext.Plo
-rm -f ./$(DEPDIR)/gg_rttopo.Plo
-rm -f ./$(DEPDIR)/gg_shape.Plo
-rm -f ./$(DEPDIR)/gg_transform.Plo
-rm -f ./$(DEPDIR)/gg_vanuatu.Plo
-rm -f ./$(DEPDIR)/gg_voronoj.Plo
-rm -f ./$(DEPDIR)/gg_wkb.Plo
-rm -f ./$(DEPDIR)/gg_wkt.Plo
-rm -f ./$(DEPDIR)/gg_xml.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--depfiles check check-am clean clean-generic clean-libtool \
clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
libspatialite-5.1.0/src/gaiageo/gg_advanced.c 0000644 0001750 0001750 00000313765 14463127014 016056 0000000 0000000 /*
gg_advanced.c -- Gaia advanced geometric operations
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#include
#include
GAIAGEO_DECLARE double
gaiaMeasureLength (int dims, double *coords, int vert)
{
/* computes the total length */
double lung = 0.0;
double xx1;
double xx2;
double yy1;
double yy2;
double x;
double y;
double z;
double m;
double dist;
int ind;
if (vert <= 0)
return lung;
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, 0, &xx1, &yy1, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, 0, &xx1, &yy1, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, 0, &xx1, &yy1, &z, &m);
}
else
{
gaiaGetPoint (coords, 0, &xx1, &yy1);
}
for (ind = 1; ind < vert; ind++)
{
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, ind, &xx2, &yy2, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, ind, &xx2, &yy2, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, ind, &xx2, &yy2, &z, &m);
}
else
{
gaiaGetPoint (coords, ind, &xx2, &yy2);
}
x = xx1 - xx2;
y = yy1 - yy2;
dist = sqrt ((x * x) + (y * y));
lung += dist;
xx1 = xx2;
yy1 = yy2;
}
return lung;
}
GAIAGEO_DECLARE double
gaiaMeasureArea (gaiaRingPtr ring)
{
/* computes the area */
int iv;
double xx;
double yy;
double x;
double y;
double z;
double m;
double area = 0.0;
if (!ring)
return 0.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ring->Coords, 0, &xx, &yy, &z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ring->Coords, 0, &xx, &yy, &m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ring->Coords, 0, &xx, &yy, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, 0, &xx, &yy);
}
for (iv = 1; iv < ring->Points; iv++)
{
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);
}
area += ((xx * y) - (x * yy));
xx = x;
yy = y;
}
area /= 2.0;
return fabs (area);
}
GAIAGEO_DECLARE void
gaiaRingCentroid (gaiaRingPtr ring, double *rx, double *ry)
{
/* computes the simple ring centroid */
double cx = 0.0;
double cy = 0.0;
double xx;
double yy;
double x;
double y;
double z;
double m;
double coeff;
double area;
double term;
int iv;
if (!ring)
{
*rx = -DBL_MAX;
*ry = -DBL_MAX;
return;
}
area = gaiaMeasureArea (ring);
coeff = 1.0 / (area * 6.0);
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ring->Coords, 0, &xx, &yy, &z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ring->Coords, 0, &xx, &yy, &m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ring->Coords, 0, &xx, &yy, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, 0, &xx, &yy);
}
for (iv = 1; iv < ring->Points; iv++)
{
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);
}
term = (xx * y) - (x * yy);
cx += (xx + x) * term;
cy += (yy + y) * term;
xx = x;
yy = y;
}
*rx = fabs (cx * coeff);
*ry = fabs (cy * coeff);
}
GAIAGEO_DECLARE void
gaiaClockwise (gaiaRingPtr p)
{
/* determines clockwise or anticlockwise direction */
int ind;
int ix;
double xx;
double yy;
double x;
double y;
double z;
double m;
double area = 0.0;
for (ind = 0; ind < p->Points; ind++)
{
if (p->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (p->Coords, ind, &xx, &yy, &z);
}
else if (p->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (p->Coords, ind, &xx, &yy, &m);
}
else if (p->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (p->Coords, ind, &xx, &yy, &z, &m);
}
else
{
gaiaGetPoint (p->Coords, ind, &xx, &yy);
}
ix = (ind + 1) % p->Points;
if (p->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (p->Coords, ix, &x, &y, &z);
}
else if (p->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (p->Coords, ix, &x, &y, &m);
}
else if (p->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (p->Coords, ix, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (p->Coords, ix, &x, &y);
}
area += ((xx * y) - (x * yy));
}
area /= 2.0;
if (area >= 0.0)
p->Clockwise = 0;
else
p->Clockwise = 1;
}
GAIAGEO_DECLARE double
gaiaCurvosityIndex (const void *p_cache, gaiaLinestringPtr ln, int extra_points)
{
/* calculates the Curvosity Index of some Linestring */
#ifndef OMIT_GEOS /* including GEOS */
double x;
double y;
double z;
double m;
int iv;
int ov;
gaiaGeomCollPtr geo = NULL;
gaiaLinestringPtr refln = NULL;
double refline_length;
double line_length =
gaiaMeasureLength (ln->DimensionModel, ln->Coords, ln->Points);
/* building the Reference Line */
refln = gaiaAllocLinestring (2 + extra_points);
/* inserting the first vertex of Line into the Reference Line */
iv = 0;
ov = 0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
gaiaSetPoint (refln->Coords, 0, x, y);
ov++;
if (extra_points > 0)
{
/* inserting all interpolated points into the Reference Line */
int i;
double perc = 1.0 / (double) (extra_points + 1);
double progr = perc;
gaiaGeomCollPtr geo;
gaiaGeomCollPtr result;
gaiaPointPtr pt;
if (ln->DimensionModel == GAIA_XY_Z)
geo = gaiaAllocGeomCollXYZ ();
else if (ln->DimensionModel == GAIA_XY_M)
geo = gaiaAllocGeomCollXYM ();
else if (ln->DimensionModel == GAIA_XY_Z_M)
geo = gaiaAllocGeomCollXYZM ();
else
geo = gaiaAllocGeomColl ();
gaiaInsertLinestringInGeomColl (geo, ln);
for (i = 0; i < extra_points; i++)
{
if (p_cache != NULL)
result = gaiaLineInterpolatePoint_r (p_cache, geo, progr);
else
result = gaiaLineInterpolatePoint (geo, progr);
if (result == NULL)
goto error;
pt = result->FirstPoint;
if (pt == NULL)
goto error;
x = pt->X;
y = pt->Y;
gaiaFreeGeomColl (result);
gaiaSetPoint (refln->Coords, ov, x, y);
ov++;
progr += perc;
}
geo->FirstLinestring = NULL; /* releasing ownership on Line */
geo->LastLinestring = NULL;
gaiaFreeGeomColl (geo);
}
/* inserting the last vertex of Line into the Reference Line */
iv = ln->Points - 1;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
gaiaSetPoint (refln->Coords, ov, x, y);
refline_length =
gaiaMeasureLength (refln->DimensionModel, refln->Coords, refln->Points);
gaiaFreeLinestring(refln);
return (refline_length / line_length);
error:
if (geo != NULL)
{
geo->FirstLinestring = NULL; /* releasing ownership on Line */
geo->LastLinestring = NULL;
gaiaFreeGeomColl (geo);
}
if (refln != NULL)
gaiaFreeLinestring(refln);
#endif /* end including GEOS */
return -1.0;
}
GAIAGEO_DECLARE void
gaiaUpDownHeight (gaiaLinestringPtr ln, double *up, double *down)
{
/* calculates the Uphill and Downhill Height of some Linestring */
double x;
double y;
double z;
double m;
int iv;
double prev_z;
double tot_up = 0.0;
double tot_down = 0.0;
/* inserting the last vertex of Line into the Reference Line */
if (ln->DimensionModel == GAIA_XY || ln->DimensionModel == GAIA_XY_M)
{
*up = 0.0;
*down = 0.0;
goto stop;
}
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
if (iv == 0)
{
prev_z = z;
continue;
}
if (z > prev_z)
tot_up += z - prev_z;
else
tot_down += prev_z - z;
prev_z = z;
}
stop:
*up = tot_up;
*down = tot_down;
}
GAIAGEO_DECLARE int
gaiaIsPointOnRingSurface (gaiaRingPtr ring, double pt_x, double pt_y)
{
/* tests if a POINT falls inside a RING */
int isInternal = 0;
int cnt;
int i;
int j;
double x;
double y;
double z;
double m;
double *vert_x;
double *vert_y;
double minx = DBL_MAX;
double miny = DBL_MAX;
double maxx = -DBL_MAX;
double maxy = -DBL_MAX;
cnt = ring->Points;
cnt--; /* ignoring last vertex because surely identical to the first one */
if (cnt < 2)
return 0;
/* allocating and loading an array of vertices */
vert_x = malloc (sizeof (double) * (cnt));
vert_y = malloc (sizeof (double) * (cnt));
for (i = 0; i < cnt; i++)
{
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ring->Coords, i, &x, &y, &z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ring->Coords, i, &x, &y, &m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ring->Coords, i, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, i, &x, &y);
}
vert_x[i] = x;
vert_y[i] = y;
if (x < minx)
minx = x;
if (x > maxx)
maxx = x;
if (y < miny)
miny = y;
if (y > maxy)
maxy = y;
}
if (pt_x < minx || pt_x > maxx)
goto end; /* outside the bounding box (x axis) */
if (pt_y < miny || pt_y > maxy)
goto end; /* outside the bounding box (y axis) */
for (i = 0, j = cnt - 1; i < cnt; j = i++)
{
/* The definitive reference is "Point in Polyon Strategies" by
/ Eric Haines [Gems IV] pp. 24-46.
/ The code in the Sedgewick book Algorithms (2nd Edition, p.354) is
/ incorrect.
*/
if ((((vert_y[i] <= pt_y) && (pt_y < vert_y[j]))
|| ((vert_y[j] <= pt_y) && (pt_y < vert_y[i])))
&& (pt_x <
(vert_x[j] - vert_x[i]) * (pt_y - vert_y[i]) / (vert_y[j] -
vert_y[i]) +
vert_x[i]))
isInternal = !isInternal;
}
end:
free (vert_x);
free (vert_y);
return isInternal;
}
GAIAGEO_DECLARE double
gaiaMinDistance (double x0, double y0, int dims, double *coords, int n_vert)
{
/* computing minimal distance between a POINT and a linestring/ring */
double x;
double y;
double z;
double m;
double ox;
double oy;
double lineMag;
double u;
double px;
double py;
double dist;
double min_dist = DBL_MAX;
int iv;
if (n_vert < 2)
return min_dist; /* not a valid linestring */
/* computing distance from first vertex */
ox = *(coords + 0);
oy = *(coords + 1);
min_dist = sqrt (((x0 - ox) * (x0 - ox)) + ((y0 - oy) * (y0 - oy)));
for (iv = 1; iv < n_vert; iv++)
{
/* segment start-end coordinates */
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv - 1, &ox, &oy, &z);
gaiaGetPointXYZ (coords, iv, &x, &y, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv - 1, &ox, &oy, &m);
gaiaGetPointXYM (coords, iv, &x, &y, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv - 1, &ox, &oy, &z, &m);
gaiaGetPointXYZM (coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (coords, iv - 1, &ox, &oy);
gaiaGetPoint (coords, iv, &x, &y);
}
/* computing distance from vertex */
dist = sqrt (((x0 - x) * (x0 - x)) + ((y0 - y) * (y0 - y)));
if (dist < min_dist)
min_dist = dist;
/* computing a projection */
lineMag = ((x - ox) * (x - ox)) + ((y - oy) * (y - oy));
u = (((x0 - ox) * (x - ox)) + ((y0 - oy) * (y - oy))) / lineMag;
if (u < 0.0 || u > 1.0)
; /* closest point does not fall within the line segment */
else
{
px = ox + u * (x - ox);
py = oy + u * (y - oy);
dist = sqrt (((x0 - px) * (x0 - px)) + ((y0 - py) * (y0 - py)));
if (dist < min_dist)
min_dist = dist;
}
}
return min_dist;
}
GAIAGEO_DECLARE int
gaiaIsPointOnPolygonSurface (gaiaPolygonPtr polyg, double x, double y)
{
/* tests if a POINT falls inside a POLYGON */
int ib;
gaiaRingPtr ring = polyg->Exterior;
if (gaiaIsPointOnRingSurface (ring, x, y))
{
/* ok, the POINT falls inside the polygon */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
if (gaiaIsPointOnRingSurface (ring, x, y))
{
/* no, the POINT fall inside some hole */
return 0;
}
}
return 1;
}
return 0;
}
GAIAGEO_DECLARE int
gaiaIntersect (double *x0, double *y0, double x1, double y1, double x2,
double y2, double x3, double y3, double x4, double y4)
{
/* computes intersection [if any] between two line segments
/ the intersection POINT has coordinates (x0, y0)
/ first line is identified by(x1, y1) and (x2, y2)
/ second line is identified by (x3, y3) and (x4, y4)
*/
double x;
double y;
double a1;
double b1;
double c1;
double a2;
double b2;
double c2;
double m1;
double m2;
double p;
double det_inv;
double minx1;
double miny1;
double maxx1;
double maxy1;
double minx2;
double miny2;
double maxx2;
double maxy2;
int ok1 = 0;
int ok2 = 0;
/* building line segment's MBRs */
if (x2 < x1)
{
minx1 = x2;
maxx1 = x1;
}
else
{
minx1 = x1;
maxx1 = x2;
}
if (y2 < y1)
{
miny1 = y2;
maxy1 = y1;
}
else
{
miny1 = y1;
maxy1 = y2;
}
if (x4 < x3)
{
minx2 = x4;
maxx2 = x3;
}
else
{
minx2 = x3;
maxx2 = x4;
}
if (y4 < y3)
{
miny2 = y4;
maxy2 = y3;
}
else
{
miny2 = y3;
maxy2 = y4;
}
/* checking MBRs first */
if (minx1 > maxx2)
return 0;
if (miny1 > maxy2)
return 0;
if (maxx1 < minx2)
return 0;
if (maxy1 < miny2)
return 0;
if (minx2 > maxx1)
return 0;
if (miny2 > maxy1)
return 0;
if (maxx2 < minx1)
return 0;
if (maxy2 < miny1)
return 0;
/* there is an MBRs intersection - proceeding */
if ((x2 - x1) != 0.0)
m1 = (y2 - y1) / (x2 - x1);
else
m1 = DBL_MAX;
if ((x4 - x3) != 0)
m2 = (y4 - y3) / (x4 - x3);
else
m2 = DBL_MAX;
if (m1 == m2) /* parallel lines */
return 0;
if (m1 == DBL_MAX)
c1 = y1;
else
c1 = (y1 - m1 * x1);
if (m2 == DBL_MAX)
c2 = y3;
else
c2 = (y3 - m2 * x3);
if (m1 == DBL_MAX)
{
x = x1;
p = m2 * x1;
y = p + c2; /* first line is vertical */
goto check_bbox;
}
if (m2 == DBL_MAX)
{
x = x3;
p = m1 * x3;
y = p + c1; /* second line is vertical */
goto check_bbox;
}
a1 = m1;
a2 = m2;
b1 = -1;
b2 = -1;
det_inv = 1 / (a1 * b2 - a2 * b1);
x = ((b1 * c2 - b2 * c1) * det_inv);
y = ((a2 * c1 - a1 * c2) * det_inv);
/* now checking if intersection falls within both segment boundaries */
check_bbox:
if (x >= minx1 && x <= maxx1 && y >= miny1 && y <= maxy1)
ok1 = 1;
if (x >= minx2 && x <= maxx2 && y >= miny2 && y <= maxy2)
ok2 = 1;
if (ok1 && ok2)
{
/* intersection point falls within the segments */
*x0 = x;
*y0 = y;
return 1;
}
return 0;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSanitize (gaiaGeomCollPtr geom)
{
/*
/ sanitizes a GEOMETRYCOLLECTION:
/ - repeated vertices are omitted
/ - ring closure is enforced anyway
*/
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
int points;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y, point->Z,
point->M);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* sanitizing LINESTRINGs */
points = 0;
for (iv = 0; iv < line->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
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);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (points < 2)
{
/* illegal LINESTRING - copying the original one */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
}
else
{
/* valid LINESTRING - sanitizing */
new_line = gaiaAddLinestringToGeomColl (new_geom, points);
points = 0;
for (iv = 0; iv < line->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
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);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
{
if (new_line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_line->Coords,
points, x, y, z);
}
else if (new_line->DimensionModel ==
GAIA_XY_M)
{
gaiaSetPointXYM (new_line->Coords,
points, x, y, m);
}
else if (new_line->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_line->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (new_line->Coords, points,
x, y);
}
points++;
}
}
else
{
if (new_line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_line->Coords, points, x,
y, z);
}
else if (new_line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_line->Coords, points, x,
y, m);
}
else if (new_line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_line->Coords, points, x,
y, z, m);
}
else
{
gaiaSetPoint (new_line->Coords, points, x, y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
/* sanitizing EXTERIOR RING */
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (last_x == x && last_y == y && last_z == z)
;
else
{
/* forcing RING closure */
points++;
}
if (points < 4)
{
/* illegal RING - copying the original one */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* valid RING - sanitizing */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points,
x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points,
x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x,
y);
}
points++;
}
}
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points, x,
y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points, x,
y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, points, x,
y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x, y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
}
/* PASS III - forcing RING closure */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
points = o_ring->Points - 1;
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points, x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points, x, y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x, y);
}
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
/* sanitizing an INTERIOR RING */
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (last_x == x && last_y == y && last_z == z)
;
else
{
/* forcing RING closure */
points++;
}
if (points < 4)
{
/* illegal RING - copying the original one */
o_ring =
gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* valid RING - sanitizing */
o_ring = gaiaAddInteriorRing (new_polyg, ib, points);
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y,
&z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y,
&m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords,
points, x, y, z);
}
else if (o_ring->DimensionModel ==
GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords,
points, x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z,
m);
}
else
{
gaiaSetPoint (o_ring->Coords,
points, x, y);
}
points++;
}
}
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points,
x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points,
x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x,
y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
/* PASS III - forcing RING closure */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
points = o_ring->Points - 1;
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points, x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points, x, y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, points, x, y, z,
m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x, y);
}
}
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaEnsureClosedRings (gaiaGeomCollPtr geom)
{
/*
/ sanitizes a GEOMETRYCOLLECTION:
/ - ring closure is enforced anyway
*/
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
int points;
int end_point;
int enforce;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y, point->Z,
point->M);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
/* sanitizing EXTERIOR RING */
points = i_ring->Points;
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
last_z = 0.0;
m = 0.0;
end_point = points - 1;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, end_point, &last_x, &last_y,
&last_z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, end_point, &last_x, &last_y,
&m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, end_point, &last_x, &last_y,
&last_z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, end_point, &last_x, &last_y);
}
if (last_x == x && last_y == y && last_z == z)
enforce = 0;
else
{
/* forcing RING closure */
enforce = 1;
}
if (!enforce)
{
/* already closed */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* forcing closure */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points + 1,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, iv, x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, iv, x, y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, iv, x, y);
}
}
/* adding last vertex so to ensure closure */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
end_point = o_ring->Points - 1;
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, end_point, x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, end_point, x, y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, end_point, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, end_point, x, y);
}
}
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
points = i_ring->Points;
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
last_z = 0.0;
m = 0.0;
end_point = points - 1;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, end_point, &last_x,
&last_y, &last_z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, end_point, &last_x,
&last_y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, end_point, &last_x,
&last_y, &last_z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, end_point, &last_x,
&last_y);
}
last_z = z;
if (last_x == x && last_y == y && last_z == z)
enforce = 0;
else
{
/* forcing RING closure */
enforce = 1;
}
if (!enforce)
{
/* already closed */
o_ring =
gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* forcing closure */
o_ring =
gaiaAddInteriorRing (new_polyg, ib,
i_ring->Points + 1);
for (iv = 0; iv < i_ring->Points; iv++)
{
/* inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y,
&z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y,
&m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, iv, x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, iv, x, y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
iv, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, iv, x, y);
}
}
/* adding last vertex so to ensure closure */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, 0, &x, &y);
}
end_point = o_ring->Points - 1;
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, end_point, x, y,
z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, end_point, x, y,
m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, end_point, x, y,
z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, end_point, x, y);
}
}
}
polyg = polyg->Next;
}
return new_geom;
}
static double
point_point_distance (double x1, double y1, double x2, double y2)
{
return sqrt (((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
}
static int
repeated_matching_point (gaiaGeomCollPtr geom, double x, double y, double z,
double tolerance)
{
/* checking for duplicate points - multipoint */
gaiaPointPtr point;
point = geom->FirstPoint;
while (point)
{
if (tolerance <= 0.0)
{
if (point->X == x && point->Y == y && point->Z == z)
return 1;
}
else
{
if (point_point_distance (x, y, point->X, point->Y) <=
tolerance)
return 1;
}
point = point->Next;
}
return 0;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaRemoveRepeatedPoints (gaiaGeomCollPtr geom, double tolerance)
{
/*
/ sanitizes a GEOMETRYCOLLECTION:
/ - repeated vertices are omitted
*/
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
int points;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (!repeated_matching_point
(new_geom, point->X, point->Y, point->Z, tolerance))
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, point->M);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* sanitizing LINESTRINGs */
points = 0;
for (iv = 0; iv < line->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
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);
}
if (iv > 0)
{
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
{
if (point_point_distance (x, y, last_x, last_y) <=
tolerance)
;
else
points++;
}
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (points < 2)
{
/* illegal LINESTRING - copying the original one */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
}
else
{
/* valid LINESTRING - sanitizing */
new_line = gaiaAddLinestringToGeomColl (new_geom, points);
points = 0;
for (iv = 0; iv < line->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
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);
}
if (iv > 0)
{
int skip = 0;
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y && last_z == z)
skip = 1;
}
else
{
if (point_point_distance
(x, y, last_x, last_y) <= tolerance)
skip = 1;
}
if (skip)
;
else
{
if (new_line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_line->Coords,
points, x, y, z);
}
else if (new_line->DimensionModel ==
GAIA_XY_M)
{
gaiaSetPointXYM (new_line->Coords,
points, x, y, m);
}
else if (new_line->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_line->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (new_line->Coords, points,
x, y);
}
points++;
}
}
else
{
if (new_line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_line->Coords, points, x,
y, z);
}
else if (new_line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_line->Coords, points, x,
y, m);
}
else if (new_line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_line->Coords, points, x,
y, z, m);
}
else
{
gaiaSetPoint (new_line->Coords, points, x, y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
/* sanitizing EXTERIOR RING */
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
{
if (point_point_distance (x, y, last_x, last_y) <=
tolerance)
;
else
points++;
}
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (points < 4)
{
/* illegal RING - copying the original one */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* valid RING - sanitizing */
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
int skip = 0;
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y && last_z == z)
skip = 1;
}
else
{
if (point_point_distance
(x, y, last_x, last_y) <= tolerance)
skip = 1;
}
if (skip)
;
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points,
x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points,
x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x,
y);
}
points++;
}
}
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points, x,
y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points, x,
y, m);
}
else if (o_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords, points, x,
y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x, y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
}
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
/* sanitizing an INTERIOR RING */
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS I - checking points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y && last_z == z)
;
else
points++;
}
else
{
if (point_point_distance
(x, y, last_x, last_y) <= tolerance)
;
else
points++;
}
}
else
points++;
last_x = x;
last_y = y;
last_z = z;
}
if (points < 4)
{
/* illegal RING - copying the original one */
o_ring =
gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* valid RING - sanitizing */
o_ring = gaiaAddInteriorRing (new_polyg, ib, points);
points = 0;
for (iv = 0; iv < i_ring->Points; iv++)
{
/* PASS II - inserting points */
z = 0.0;
m = 0.0;
if (i_ring->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y,
&z);
}
else if (i_ring->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (i_ring->Coords, iv, &x, &y,
&m);
}
else if (i_ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (i_ring->Coords, iv, &x, &y);
}
if (iv > 0)
{
int skip = 0;
if (tolerance <= 0.0)
{
if (last_x == x && last_y == y
&& last_z == z)
skip = 1;
}
else
{
if (point_point_distance
(x, y, last_x, last_y) <= tolerance)
skip = 1;
}
if (skip)
;
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords,
points, x, y, z);
}
else if (o_ring->DimensionModel ==
GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords,
points, x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z,
m);
}
else
{
gaiaSetPoint (o_ring->Coords,
points, x, y);
}
points++;
}
}
else
{
if (o_ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (o_ring->Coords, points,
x, y, z);
}
else if (o_ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (o_ring->Coords, points,
x, y, m);
}
else if (o_ring->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM (o_ring->Coords,
points, x, y, z, m);
}
else
{
gaiaSetPoint (o_ring->Coords, points, x,
y);
}
points++;
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
polyg = polyg->Next;
}
return new_geom;
}
static int
gaiaIsToxicLinestring (gaiaLinestringPtr line)
{
/* checking a Linestring */
if (line->Points < 2)
return 1;
/* not a valid Linestring, simply a degenerated Point */
return 0;
}
static int
gaiaIsToxicRing (gaiaRingPtr ring)
{
/* checking a Ring */
if (ring->Points < 4)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaIsToxic (gaiaGeomCollPtr geom)
{
return gaiaIsToxic_r (NULL, geom);
}
GAIAGEO_DECLARE int
gaiaIsToxic_r (const void *cache, gaiaGeomCollPtr geom)
{
/*
/ identifying toxic geometries
/ i.e. geoms making GEOS to crash !!!
*/
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
if (!geom)
return 0;
if (gaiaIsEmpty (geom))
return 1;
point = geom->FirstPoint;
while (point)
{
/* checking POINTs */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* checking LINESTRINGs */
if (gaiaIsToxicLinestring (line))
{
if (cache != NULL)
gaiaSetGeosAuxErrorMsg_r
(cache,
"gaiaIsToxic detected a toxic Linestring: < 2 pts");
else
gaiaSetGeosAuxErrorMsg
("gaiaIsToxic detected a toxic Linestring: < 2 pts");
return 1;
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* checking POLYGONs */
ring = polyg->Exterior;
if (gaiaIsToxicRing (ring))
{
if (cache != NULL)
gaiaSetGeosAuxErrorMsg_r
(cache, "gaiaIsToxic detected a toxic Ring: < 4 pts");
else
gaiaSetGeosAuxErrorMsg
("gaiaIsToxic detected a toxic Ring: < 4 pts");
return 1;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
if (gaiaIsToxicRing (ring))
{
if (cache != NULL)
gaiaSetGeosAuxErrorMsg_r
(cache,
"gaiaIsToxic detected a toxic Ring: < 4 pts");
else
gaiaSetGeosAuxErrorMsg
("gaiaIsToxic detected a toxic Ring: < 4 pts");
return 1;
}
}
polyg = polyg->Next;
}
return 0;
}
GAIAGEO_DECLARE int
gaiaIsNotClosedRing (gaiaRingPtr ring)
{
return gaiaIsNotClosedRing_r (NULL, ring);
}
GAIAGEO_DECLARE int
gaiaIsNotClosedRing_r (const void *cache, gaiaRingPtr ring)
{
/* checking a Ring for closure */
double x0;
double y0;
double z0;
double m0;
double x1;
double y1;
double z1;
double m1;
gaiaRingGetPoint (ring, 0, &x0, &y0, &z0, &m0);
gaiaRingGetPoint (ring, ring->Points - 1, &x1, &y1, &z1, &m1);
if (x0 == x1 && y0 == y1 && z0 == z1 && m0 == m1)
return 0;
else
{
if (cache != NULL)
gaiaSetGeosAuxErrorMsg_r (cache,
"gaia detected a not-closed Ring");
else
gaiaSetGeosAuxErrorMsg ("gaia detected a not-closed Ring");
return 1;
}
}
GAIAGEO_DECLARE int
gaiaIsNotClosedGeomColl (gaiaGeomCollPtr geom)
{
return gaiaIsNotClosedGeomColl_r (NULL, geom);
}
GAIAGEO_DECLARE int
gaiaIsNotClosedGeomColl_r (const void *cache, gaiaGeomCollPtr geom)
{
/*
/ identifying not properly closed Rings
/ i.e. geoms making GEOS to crash !!!
*/
int ret;
int ib;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
if (!geom)
return 0;
polyg = geom->FirstPolygon;
while (polyg)
{
/* checking POLYGONs */
ring = polyg->Exterior;
if (cache != NULL)
ret = gaiaIsNotClosedRing_r (cache, ring);
else
ret = gaiaIsNotClosedRing (ring);
if (ret)
return 1;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
if (cache != NULL)
ret = gaiaIsNotClosedRing_r (cache, ring);
else
ret = gaiaIsNotClosedRing (ring);
if (ret)
return 1;
}
polyg = polyg->Next;
}
return 0;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLinearize (gaiaGeomCollPtr geom, int force_multi)
{
/* attempts to rearrange a generic Geometry into a (multi)linestring */
int pts = 0;
int lns = 0;
gaiaGeomCollPtr result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr new_ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int iv;
int ib;
double x;
double y;
double m;
double z;
if (!geom)
return NULL;
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
if (pts || lns)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
result->Srid = geom->Srid;
if (force_multi)
result->DeclaredType = GAIA_MULTILINESTRING;
pg = geom->FirstPolygon;
while (pg)
{
/* dissolving any POLYGON as simple LINESTRINGs (rings) */
rng = pg->Exterior;
new_ln = gaiaAddLinestringToGeomColl (result, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* copying the EXTERIOR RING as LINESTRING */
if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
new_ln = gaiaAddLinestringToGeomColl (result, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* copying an INTERIOR RING as LINESTRING */
if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
}
pg = pg->Next;
}
if (result->FirstLinestring == NULL)
{
gaiaFreeGeomColl (result);
return NULL;
}
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDissolveSegments (gaiaGeomCollPtr geom)
{
/* attempts to dissolve a Geometry into segments */
gaiaGeomCollPtr result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr segment;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
double x0 = 0.0;
double y0 = 0.0;
double z0 = 0.0;
double m0 = 0.0;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
pt = geom->FirstPoint;
while (pt)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M);
else
gaiaAddPointToGeomColl (result, pt->X, pt->Y);
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (x != x0 || y != y0 || z != z0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYZM (segment->Coords, 0, x0, y0,
z0, m0);
gaiaSetPointXYZM (segment->Coords, 1, x, y, z,
m);
}
}
else if (geom->DimensionModel == GAIA_XY_Z)
{
if (x != x0 || y != y0 || z != z0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYZ (segment->Coords, 0, x0, y0,
z0);
gaiaSetPointXYZ (segment->Coords, 1, x, y, z);
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
if (x != x0 || y != y0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYM (segment->Coords, 0, x0, y0,
m0);
gaiaSetPointXYM (segment->Coords, 1, x, y, m);
}
}
else
{
if (x != x0 || y != y0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (segment->Coords, 0, x0, y0);
gaiaSetPoint (segment->Coords, 1, x, y);
}
}
}
x0 = x;
y0 = y;
z0 = z;
m0 = m;
}
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
for (iv = 0; iv < rng->Points; iv++)
{
/* exterior Ring */
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (x != x0 || y != y0 || z != z0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYZM (segment->Coords, 0, x0, y0,
z0, m0);
gaiaSetPointXYZM (segment->Coords, 1, x, y, z,
m);
}
}
else if (geom->DimensionModel == GAIA_XY_Z)
{
if (x != x0 || y != y0 || z != z0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYZ (segment->Coords, 0, x0, y0,
z0);
gaiaSetPointXYZ (segment->Coords, 1, x, y, z);
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
if (x != x0 || y != y0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPointXYM (segment->Coords, 0, x0, y0,
m0);
gaiaSetPointXYM (segment->Coords, 1, x, y, m);
}
}
else
{
if (x != x0 || y != y0)
{
segment =
gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (segment->Coords, 0, x0, y0);
gaiaSetPoint (segment->Coords, 1, x, y);
}
}
}
x0 = x;
y0 = y;
z0 = z;
m0 = m;
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
for (iv = 0; iv < rng->Points; iv++)
{
/* interior Ring */
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (iv > 0)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (x != x0 || y != y0 || z != z0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result,
2);
gaiaSetPointXYZM (segment->Coords, 0,
x0, y0, z0, m0);
gaiaSetPointXYZM (segment->Coords, 1, x,
y, z, m);
}
}
else if (geom->DimensionModel == GAIA_XY_Z)
{
if (x != x0 || y != y0 || z != z0)
{
segment =
gaiaAddLinestringToGeomColl (result,
2);
gaiaSetPointXYZ (segment->Coords, 0, x0,
y0, z0);
gaiaSetPointXYZ (segment->Coords, 1, x,
y, z);
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
if (x != x0 || y != y0 || m != m0)
{
segment =
gaiaAddLinestringToGeomColl (result,
2);
gaiaSetPointXYM (segment->Coords, 0, x0,
y0, m0);
gaiaSetPointXYM (segment->Coords, 1, x,
y, m);
}
}
else
{
if (x != x0 || y != y0)
{
segment =
gaiaAddLinestringToGeomColl (result,
2);
gaiaSetPoint (segment->Coords, 0, x0,
y0);
gaiaSetPoint (segment->Coords, 1, x, y);
}
}
}
x0 = x;
y0 = y;
z0 = z;
m0 = m;
}
}
pg = pg->Next;
}
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDissolvePoints (gaiaGeomCollPtr geom)
{
/* attempts to dissolve a Geometry into points */
gaiaGeomCollPtr result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
pt = geom->FirstPoint;
while (pt)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M);
else
gaiaAddPointToGeomColl (result, pt->X, pt->Y);
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, x, y, z, m);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, x, y, z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, x, y, m);
else
gaiaAddPointToGeomColl (result, x, y);
}
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
for (iv = 0; iv < rng->Points; iv++)
{
/* exterior Ring */
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, x, y, z, m);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, x, y, z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, x, y, m);
else
gaiaAddPointToGeomColl (result, x, y);
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
for (iv = 0; iv < rng->Points; iv++)
{
/* interior Ring */
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, x, y, z, m);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, x, y, z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, x, y, m);
else
gaiaAddPointToGeomColl (result, x, y);
}
}
pg = pg->Next;
}
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractPointsFromGeomColl (gaiaGeomCollPtr geom)
{
/* extracts any POINT from a GeometryCollection */
gaiaGeomCollPtr result;
gaiaPointPtr pt;
int pts = 0;
if (!geom)
return NULL;
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
if (!pts)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
pt = geom->FirstPoint;
while (pt)
{
if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M);
else if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M);
else
gaiaAddPointToGeomColl (result, pt->X, pt->Y);
pt = pt->Next;
}
result->Srid = geom->Srid;
if (pts == 1)
result->DeclaredType = GAIA_POINT;
else
result->DeclaredType = GAIA_MULTIPOINT;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractLinestringsFromGeomColl (gaiaGeomCollPtr geom)
{
/* extracts any LINESTRING from a GeometryCollection */
gaiaGeomCollPtr result;
gaiaLinestringPtr ln;
gaiaLinestringPtr new_ln;
int lns = 0;
int iv;
double x;
double y;
double z;
double m;
if (!geom)
return NULL;
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
if (!lns)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
ln = geom->FirstLinestring;
while (ln)
{
new_ln = gaiaAddLinestringToGeomColl (result, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
ln = ln->Next;
}
result->Srid = geom->Srid;
if (lns == 1)
result->DeclaredType = GAIA_LINESTRING;
else
result->DeclaredType = GAIA_MULTILINESTRING;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaExtractPolygonsFromGeomColl (gaiaGeomCollPtr geom)
{
/* extracts any POLYGON from a GeometryCollection */
gaiaGeomCollPtr result;
gaiaPolygonPtr pg;
gaiaPolygonPtr new_pg;
gaiaRingPtr rng;
gaiaRingPtr new_rng;
int pgs = 0;
int iv;
int ib;
double x;
double y;
double z;
double m;
if (!geom)
return NULL;
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (!pgs)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else
result = gaiaAllocGeomColl ();
pg = geom->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
new_pg =
gaiaAddPolygonToGeomColl (result, rng->Points, pg->NumInteriors);
new_rng = new_pg->Exterior;
for (iv = 0; iv < rng->Points; iv++)
{
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_rng->Coords, iv, x, y, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_rng->Coords, iv, x, y);
}
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
new_rng = gaiaAddInteriorRing (new_pg, ib, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_rng->Coords, iv, x, y, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_rng->Coords, iv, x, y);
}
}
}
pg = pg->Next;
}
result->Srid = geom->Srid;
if (pgs == 1)
result->DeclaredType = GAIA_POLYGON;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
return result;
}
SPATIALITE_PRIVATE int
gaia_do_check_linestring (const void *g)
{
/* testing if the Geometry is a simple Linestring */
gaiaGeomCollPtr geom = (gaiaGeomCollPtr) g;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
pt = geom->FirstPoint;
while (pt != NULL)
{
/* counting how many Points are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln != NULL)
{
/* counting how many Linestrings are there */
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg != NULL)
{
/* counting how many Polygons are there */
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 1 && pgs == 0)
return 1;
return 0;
}
static int
do_create_points (sqlite3 * mem_db, const char *table)
{
/* creating a table for storing Points */
int ret;
char *sql;
char *err_msg = NULL;
/* creating the main table */
if (strcmp (table, "points1") == 0)
sql = sqlite3_mprintf ("CREATE TABLE %s "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"geom BLOB NOT NULL, "
"needs_interpolation INTEGER NOT NULL)", table);
else
sql = sqlite3_mprintf ("CREATE TABLE %s "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"geom BLOB NOT NULL)", table);
ret = sqlite3_exec (mem_db, sql, NULL, NULL, &err_msg);
sqlite3_free (sql);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaDrapeLine: CREATE TABLE \"%s\" error: %s\n",
table, err_msg);
sqlite3_free (err_msg);
return 0;
}
if (strcmp (table, "points1") == 0)
return 1;
/* creating the companion R*Tree table */
sql = sqlite3_mprintf ("CREATE VIRTUAL TABLE rtree_%s "
"USING rtree(pkid, xmin, xmax, ymin, ymax)", table);
ret = sqlite3_exec (mem_db, sql, NULL, NULL, &err_msg);
sqlite3_free (sql);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaDrapeLine: CREATE TABLE \"rtree_%s\" error: %s\n",
table, err_msg);
sqlite3_free (err_msg);
return 0;
}
return 1;
}
static int
do_insert_point (sqlite3 * mem_db, sqlite3_stmt * stmt_pts,
sqlite3_stmt * stmt_rtree_pts, double x,
double y, double z, double m)
{
/* inserting into the Points2 helper table */
int ret;
sqlite3_int64 rowid;
sqlite3_reset (stmt_pts);
sqlite3_clear_bindings (stmt_pts);
sqlite3_bind_double (stmt_pts, 1, x);
sqlite3_bind_double (stmt_pts, 2, y);
sqlite3_bind_double (stmt_pts, 3, z);
sqlite3_bind_double (stmt_pts, 4, m);
ret = sqlite3_step (stmt_pts);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
rowid = sqlite3_last_insert_rowid (mem_db);
else
{
spatialite_e ("INSERT INTO \"Points\" error: \"%s\"\n",
sqlite3_errmsg (mem_db));
goto error;
}
/* inserting into the companion R*Tree */
sqlite3_reset (stmt_rtree_pts);
sqlite3_clear_bindings (stmt_rtree_pts);
sqlite3_bind_int64 (stmt_rtree_pts, 1, rowid);
sqlite3_bind_double (stmt_rtree_pts, 2, x);
sqlite3_bind_double (stmt_rtree_pts, 3, x);
sqlite3_bind_double (stmt_rtree_pts, 4, y);
sqlite3_bind_double (stmt_rtree_pts, 5, y);
ret = sqlite3_step (stmt_rtree_pts);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
;
else
{
spatialite_e ("INSERT INTO \"RTree_Points\" error: \"%s\"\n",
sqlite3_errmsg (mem_db));
goto error;
}
return 1;
error:
return 0;
}
static int
do_populate_points2 (sqlite3 * mem_db, gaiaGeomCollPtr geom)
{
/* populating Points-2 */
int ret;
const char *sql;
int iv;
gaiaLinestringPtr ln;
sqlite3_stmt *stmt_pts = NULL;
sqlite3_stmt *stmt_rtree_pts = NULL;
double ox;
double oy;
double oz;
double om;
double fx;
double fy;
double fz;
double fm;
/* creating an SQL statement for inserting rows into the Points2 table */
sql = "INSERT INTO points2 (id, geom) VALUES "
"(NULL, MakePointZM(?, ?, ?, ?))";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt_pts, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("INSERT INTO Points2: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
/* creating an SQL statement for inserting rows into the R*TREE table */
sql = "INSERT INTO rtree_points2 (pkid, xmin, xmax, ymin, ymax) "
"VALUES (?, ?, ?, ?, ?)";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt_rtree_pts, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("INSERT INTO RTree_Points2: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
/* starting a Transaction */
sql = "BEGIN";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("BEGIN: error: %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
ln = geom->FirstLinestring;
for (iv = 0; iv < ln->Points; iv++)
{
/* processing all Vertices from the input Linestring */
double x;
double y;
double z = 0.0;
double m = 0.0;
int repeated;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
repeated = 0;
if (iv != 0)
{
/* checking for repeated points */
if (x == ox && y == oy && z == oz && m == om)
repeated = 1;
}
if (iv == ln->Points - 1)
{
/* checkink for a closed Linestring */
if (x == fx && y == fy && z == fz && m == fm)
repeated = 1;
}
if (!repeated)
{
/* inserting a Point */
if (!do_insert_point
(mem_db, stmt_pts, stmt_rtree_pts, x, y, z, m))
goto error;
}
/* saving the current coords */
ox = x;
oy = y;
oz = z;
om = m;
if (iv == 0)
{
/* saving the Start Point coords */
fx = x;
fy = y;
fz = z;
fm = m;
}
}
/* committing the pending Transaction */
sql = "COMMIT";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("COMMIT: error: %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
sqlite3_finalize (stmt_pts);
sqlite3_finalize (stmt_rtree_pts);
return 1;
error:
if (stmt_pts != NULL)
sqlite3_finalize (stmt_pts);
if (stmt_rtree_pts != NULL)
sqlite3_finalize (stmt_rtree_pts);
return 0;
}
static int
do_insert_draped_point (sqlite3 * mem_db, sqlite3_stmt * stmt_pts,
int needs_interpolation, gaiaGeomCollPtr geom)
{
/* inserting into the Points helper table */
int ret;
gaiaPointPtr pt = geom->FirstPoint;
if (pt == NULL)
return 0;
sqlite3_reset (stmt_pts);
sqlite3_clear_bindings (stmt_pts);
sqlite3_bind_double (stmt_pts, 1, pt->X);
sqlite3_bind_double (stmt_pts, 2, pt->Y);
sqlite3_bind_double (stmt_pts, 3, pt->Z);
sqlite3_bind_double (stmt_pts, 4, pt->M);
sqlite3_bind_int (stmt_pts, 5, needs_interpolation);
ret = sqlite3_step (stmt_pts);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
return 1;
spatialite_e ("INSERT INTO \"Points1\" error: \"%s\"\n",
sqlite3_errmsg (mem_db));
return 0;
}
static gaiaGeomCollPtr
do_point_drape_coords (int srid, double x, double y, gaiaGeomCollPtr geom_3d)
{
/* draping a Point */
gaiaPointPtr pt_3d = geom_3d->FirstPoint;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZM ();
geom->Srid = srid;
gaiaAddPointToGeomCollXYZM (geom, x, y, pt_3d->Z, pt_3d->M);
return geom;
}
static gaiaGeomCollPtr
do_point_same_coords (int srid, double x, double y, double z, double m)
{
/* creating a Point (unchanged coords) */
gaiaGeomCollPtr geom;
geom = gaiaAllocGeomCollXYZM ();
geom->Srid = srid;
gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
return geom;
}
static int
do_drape_vertex (sqlite3 * mem_db, sqlite3_stmt * stmt,
sqlite3_stmt * stmt_pts, int srid, double tolerance,
double x, double y, double z, double m)
{
/* draping the segment */
double minx = x;
double miny = y;
double maxx = x;
double maxy = y;
int ret;
int count = 0;
gaiaGeomCollPtr g2;
/* preparing an extendend BBOX */
minx = x - (tolerance * 2.0);
miny = y - (tolerance * 2.0);
maxx = x + (tolerance * 2.0);
maxy = y + (tolerance * 2.0);
/* querying Points-2 by distance from Segment */
sqlite3_reset (stmt);
sqlite3_clear_bindings (stmt);
sqlite3_bind_double (stmt, 1, minx); /* R*Tree BBOX */
sqlite3_bind_double (stmt, 2, miny);
sqlite3_bind_double (stmt, 3, maxx);
sqlite3_bind_double (stmt, 4, maxy);
sqlite3_bind_double (stmt, 5, x); /* point (distance) */
sqlite3_bind_double (stmt, 6, y);
sqlite3_bind_double (stmt, 7, tolerance);
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
gaiaGeomCollPtr g2 = NULL;
gaiaGeomCollPtr geom = NULL;
if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
{
unsigned char *p_blob =
(unsigned char *) sqlite3_column_blob (stmt, 0);
int n_bytes = sqlite3_column_bytes (stmt, 0);
geom = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
}
if (geom != NULL)
{
/* found a valid Point */
g2 = do_point_drape_coords (srid, x, y, geom);
gaiaFreeGeomColl (geom);
if (!do_insert_draped_point (mem_db, stmt_pts, 0, g2))
goto error;
gaiaFreeGeomColl (g2);
count++;
}
}
}
if (count == 0)
{
/* not found - inserting the Point itself */
g2 = do_point_same_coords (srid, x, y, z, m);
if (!do_insert_draped_point (mem_db, stmt_pts, 1, g2))
goto error;
gaiaFreeGeomColl (g2);
}
return 1;
error:
return 0;
}
static int
do_drape_line (sqlite3 * mem_db, gaiaGeomCollPtr geom, double tolerance)
{
/* draping the line */
int ret;
sqlite3_stmt *stmt = NULL;
sqlite3_stmt *stmt_pts = NULL;
const char *sql;
gaiaLinestringPtr ln;
int iv;
/* creating an SQL statement for querying Points-2 */
sql = "SELECT geom FROM points2 "
"WHERE ROWID IN (SELECT pkid FROM rtree_points2 WHERE "
"MbrIntersects(geom, BuildMbr(?, ?, ?, ?)) = 1) "
"AND ST_Distance(geom, MakePoint(?, ?)) <= ? " "ORDER BY id";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("SELECT Points2: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
/* creating an SQL statement for inserting rows into the Points-1 table */
sql = "INSERT INTO points1 (id, geom, needs_interpolation) VALUES "
"(NULL, MakePointZM(?, ?, ?, ?), ?)";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt_pts, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("INSERT INTO Points1: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
/* starting a Transaction */
sql = "BEGIN";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("BEGIN: error: %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
ln = geom->FirstLinestring;
for (iv = 0; iv < ln->Points; iv++)
{
/* processing all Vertices from the input Linestring */
double x;
double y;
double z = 0.0;
double m = 0.0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
/* processing a Vertex */
if (!do_drape_vertex
(mem_db, stmt, stmt_pts, geom->Srid, tolerance, x, y, z, m))
goto error;
}
/* committing the pending Transaction */
sql = "COMMIT";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("COMMIT: error: %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto error;
}
sqlite3_finalize (stmt);
sqlite3_finalize (stmt_pts);
return 1;
error:
if (stmt != NULL)
sqlite3_finalize (stmt);
if (stmt_pts != NULL)
sqlite3_finalize (stmt_pts);
return 0;
}
static int
get_prev_coords (int index, gaiaDynamicLinePtr dyn, double *z, double *m,
double *dist)
{
/* retrieving the previous Point */
double ox;
double oy;
double x;
double y;
double zz;
double mm;
int ok = 0;
int count = 0;
gaiaPointPtr pt = dyn->First;
while (pt != NULL)
{
if (index - 1 == count)
{
/* this is the previous point */
ox = pt->X;
oy = pt->Y;
zz = pt->Z;
mm = pt->M;
ok = 1;
}
if (index == count)
{
/* this is the current point */
x = pt->X;
y = pt->Y;
if (ok)
{
*z = zz;
*m = mm;
*dist =
sqrt (((ox - x) * (ox - x)) + ((oy - y) * (oy - y)));
return 1;
}
return 0;
}
count++;
pt = pt->Next;
}
return 0;
}
static int
get_next_coords (int index, gaiaDynamicLinePtr dyn, const char *interpolate,
double *z, double *m, double *dist)
{
/* retrieving the next Point */
double ox;
double oy;
double x;
double y;
double d = 0.0;
int ok = 0;
int count = 0;
gaiaPointPtr pt = dyn->First;
while (pt != NULL)
{
if (index == count)
{
/* this is the current Point */
ox = pt->X;
oy = pt->Y;
ok = 1;
}
if (index < count)
{
/* this is a following Point */
if (!ok)
return 0;
x = pt->X;
y = pt->Y;
d += sqrt (((ox - x) * (ox - x)) + ((oy - y) * (oy - y)));
if (*(interpolate + count) == 'N')
{
/* found a valid Point */
*z = pt->Z;
*m = pt->M;
*dist = d;
return 1;
}
}
count++;
pt = pt->Next;
}
return 0;
}
static int
do_update_coords (int index, gaiaDynamicLinePtr dyn, double z, double m)
{
/* updating the coords */
int count = 0;
gaiaPointPtr pt = dyn->First;
while (pt != NULL)
{
if (index == count)
{
pt->Z = z;
pt->M = m;
return 1;
}
count++;
pt = pt->Next;
}
return 0;
}
static void
do_interpolate_coords (int index, gaiaDynamicLinePtr dyn, char *interpolate)
{
/* attempting to interpolate coords */
double pz;
double pm;
double nz;
double nm;
double z;
double m;
double pdist;
double ndist;
double perc;
if (!get_prev_coords (index, dyn, &pz, &pm, &pdist))
return;
if (!get_next_coords (index, dyn, interpolate, &nz, &nm, &ndist))
return;
perc = pdist / (pdist + ndist);
z = pz + ((nz - pz) * perc);
m = pm + ((nm - pm) * perc);
if (do_update_coords (index, dyn, z, m))
*(interpolate + index) = 'I';
}
static gaiaGeomCollPtr
do_reassemble_line (sqlite3 * mem_db, int dims, int srid)
{
/* reassembling the Linestring to be returned */
gaiaGeomCollPtr geom = NULL;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
const char *sql;
int ret;
sqlite3_stmt *stmt = NULL;
int count = 0;
int needs_interpolation = 0;
/* creating an SQL statement for querying Points-1 */
sql = "SELECT geom, needs_interpolation FROM points1 ORDER BY id";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("SELECT Points1: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto end;
}
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
gaiaGeomCollPtr g = NULL;
if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
{
unsigned char *p_blob =
(unsigned char *) sqlite3_column_blob (stmt, 0);
int n_bytes = sqlite3_column_bytes (stmt, 0);
g = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
}
if (g != NULL)
{
/* found a valid Point */
pt = g->FirstPoint;
if (dims == GAIA_XY_Z_M)
gaiaAppendPointZMToDynamicLine (dyn, pt->X, pt->Y,
pt->Z, pt->M);
else if (dims == GAIA_XY_Z)
gaiaAppendPointZToDynamicLine (dyn, pt->X, pt->Y,
pt->Z);
else if (dims == GAIA_XY_M)
gaiaAppendPointMToDynamicLine (dyn, pt->X, pt->Y,
pt->M);
else
gaiaAppendPointToDynamicLine (dyn, pt->X, pt->Y);
gaiaFreeGeomColl (g);
}
if (sqlite3_column_int (stmt, 1) == 1)
needs_interpolation = 1;
}
}
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
count++;
pt = pt->Next;
}
if (count < 2)
goto end;
if (needs_interpolation)
{
/* attempting to interpolate missing coords */
int i;
int max = count;
char *interpolate = malloc (max + 1);
memset (interpolate, '\0', max + 1);
sqlite3_reset (stmt); /* rewinding the resultset */
count = 0;
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
if (sqlite3_column_int (stmt, 1) == 0)
*(interpolate + count) = 'N';
else
*(interpolate + count) = 'Y';
count++;
}
}
for (i = 0; i < max; i++)
{
if (*(interpolate + i) == 'Y')
do_interpolate_coords (i, dyn, interpolate);
}
free (interpolate);
}
sqlite3_finalize (stmt);
stmt = NULL;
/* creating the final Linestring */
if (dims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else if (dims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (dims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else
geom = gaiaAllocGeomColl ();
geom->Srid = srid;
ln = gaiaAddLinestringToGeomColl (geom, count);
count = 0;
pt = dyn->First;
while (pt != NULL)
{
if (dims == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, count, pt->X, pt->Y,
pt->Z, pt->M);
}
else if (dims == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, count, pt->X, pt->Y, pt->Z);
}
else if (dims == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, count, pt->X, pt->Y, pt->M);
}
else
{
gaiaSetPoint (ln->Coords, count, pt->X, pt->Y);
}
count++;
pt = pt->Next;
}
end:
gaiaFreeDynamicLine (dyn);
if (stmt != NULL)
sqlite3_finalize (stmt);
return geom;
}
static gaiaGeomCollPtr
do_reassemble_multi_point (sqlite3 * mem_db, int dims, int srid,
int interpolated)
{
/* reassembling the MultiPoint to be returned */
gaiaGeomCollPtr geom = NULL;
gaiaPointPtr pt;
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
const char *sql;
int ret;
sqlite3_stmt *stmt = NULL;
int count = 0;
int needs_interpolation = 0;
char *interpolate = NULL;
/* creating an SQL statement for querying Points-1 */
sql = "SELECT geom, needs_interpolation FROM points1 ORDER BY id";
ret = sqlite3_prepare_v2 (mem_db, sql, strlen (sql), &stmt, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("SELECT Points1: error %d \"%s\"\n",
sqlite3_errcode (mem_db), sqlite3_errmsg (mem_db));
goto end;
}
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
gaiaGeomCollPtr g = NULL;
if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
{
unsigned char *p_blob =
(unsigned char *) sqlite3_column_blob (stmt, 0);
int n_bytes = sqlite3_column_bytes (stmt, 0);
g = gaiaFromSpatiaLiteBlobWkb (p_blob, n_bytes);
}
if (g != NULL)
{
/* found a valid Point */
pt = g->FirstPoint;
if (dims == GAIA_XY_Z_M)
gaiaAppendPointZMToDynamicLine (dyn, pt->X, pt->Y,
pt->Z, pt->M);
else if (dims == GAIA_XY_Z)
gaiaAppendPointZToDynamicLine (dyn, pt->X, pt->Y,
pt->Z);
else if (dims == GAIA_XY_M)
gaiaAppendPointMToDynamicLine (dyn, pt->X, pt->Y,
pt->M);
else
gaiaAppendPointToDynamicLine (dyn, pt->X, pt->Y);
gaiaFreeGeomColl (g);
}
if (sqlite3_column_int (stmt, 1) == 1)
needs_interpolation = 1;
}
}
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
count++;
pt = pt->Next;
}
if (count < 2)
goto end;
if (needs_interpolation)
{
/* attempting to interpolate missing coords */
int i;
int max = count;
interpolate = malloc (max + 1);
memset (interpolate, '\0', max + 1);
sqlite3_reset (stmt); /* rewinding the resultset */
count = 0;
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
if (sqlite3_column_int (stmt, 1) == 0)
*(interpolate + count) = 'N';
else
*(interpolate + count) = 'Y';
count++;
}
}
for (i = 0; i < max; i++)
{
if (*(interpolate + i) == 'Y')
do_interpolate_coords (i, dyn, interpolate);
}
}
sqlite3_finalize (stmt);
stmt = NULL;
/* creating the final MultiPoint */
if (dims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else if (dims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (dims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else
geom = gaiaAllocGeomColl ();
geom->Srid = srid;
geom->DeclaredType = GAIA_MULTIPOINT;
pt = dyn->First;
count = 0;
while (pt != NULL)
{
int ok = 0;
if (*(interpolate + count) == 'Y')
ok = 1;
if (!interpolated && *(interpolate + count) == 'I')
ok = 1;
if (ok)
{
if (dims == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (geom, pt->X, pt->Y, pt->Z,
pt->M);
else if (dims == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y, pt->Z);
else if (dims == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (geom, pt->X, pt->Y, pt->M);
else
gaiaAddPointToGeomColl (geom, pt->X, pt->Y);
}
count++;
pt = pt->Next;
}
end:
if (interpolate != NULL)
free (interpolate);
gaiaFreeDynamicLine (dyn);
if (stmt != NULL)
sqlite3_finalize (stmt);
return geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDrapeLine (sqlite3 * db_handle, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double tolerance)
{
/* will return a 3D Linestring by draping line-1 (2D) over line-2 (3D) */
int ret;
sqlite3 *mem_db = NULL;
void *cache;
char *sql;
char *err_msg = NULL;
gaiaGeomCollPtr geom3 = NULL;
/* arguments validation */
if (db_handle == NULL)
return NULL;
if (geom1 == NULL || geom2 == NULL)
return NULL;
if (tolerance < 0.0)
return NULL;
if (geom1->Srid != geom2->Srid)
return NULL;
if (geom1->DimensionModel != GAIA_XY)
return NULL;
if (geom2->DimensionModel != GAIA_XY_Z)
return NULL;
if (!gaia_do_check_linestring (geom1))
return NULL;
if (!gaia_do_check_linestring (geom2))
return NULL;
/* creating a Temporary MemoryDB */
ret =
sqlite3_open_v2 (":memory:", &mem_db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaDrapeLine: sqlite3_open_v2 error: %s\n",
sqlite3_errmsg (mem_db));
sqlite3_close (mem_db);
return NULL;
}
cache = spatialite_alloc_connection ();
spatialite_internal_init (mem_db, cache);
/* initializing a minimal SpatiaLite DB */
sql = "SELECT InitSpatialMetadata(1, 'NONE')";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaDrapeLine: InitSpatialMetadata() error: %s\n",
err_msg);
sqlite3_free (err_msg);
goto end;
}
/* creating the helper tables on the Temporary MemoryDB */
if (!do_create_points (mem_db, "points1"))
goto end;
if (!do_create_points (mem_db, "points2"))
goto end;
/* populating the Points-2 helper table */
if (!do_populate_points2 (mem_db, geom2))
goto end;
/* draping the first line over Points-2 */
if (!do_drape_line (mem_db, geom1, tolerance))
goto end;
/* building the final linestring to be returned */
geom3 = do_reassemble_line (mem_db, geom2->DimensionModel, geom2->Srid);
end:
/* releasing the Temporary MemoryDB */
ret = sqlite3_close (mem_db);
if (ret != SQLITE_OK)
spatialite_e ("gaiaDrapeLine: sqlite3_close() error: %s\n",
sqlite3_errmsg (mem_db));
spatialite_internal_cleanup (cache);
return geom3;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDrapeLineExceptions (sqlite3 * db_handle, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double tolerance,
int interpolated)
{
/*
* will return a 3D MultiPoint containing all Vertices from geom1
* not being correctly draped over geom2
*/
int ret;
sqlite3 *mem_db = NULL;
void *cache;
char *sql;
char *err_msg = NULL;
gaiaGeomCollPtr geom3 = NULL;
/* arguments validation */
if (db_handle == NULL)
return NULL;
if (geom1 == NULL || geom2 == NULL)
return NULL;
if (tolerance < 0.0)
return NULL;
if (geom1->Srid != geom2->Srid)
return NULL;
if (geom1->DimensionModel != GAIA_XY)
return NULL;
if (geom2->DimensionModel != GAIA_XY_Z)
return NULL;
if (!gaia_do_check_linestring (geom1))
return NULL;
if (!gaia_do_check_linestring (geom2))
return NULL;
/* creating a Temporary MemoryDB */
ret =
sqlite3_open_v2 (":memory:", &mem_db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaDrapeLine: sqlite3_open_v2 error: %s\n",
sqlite3_errmsg (mem_db));
sqlite3_close (mem_db);
return NULL;
}
cache = spatialite_alloc_connection ();
spatialite_internal_init (mem_db, cache);
/* initializing a minimal SpatiaLite DB */
sql = "SELECT InitSpatialMetadata(1, 'NONE')";
ret = sqlite3_exec (mem_db, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
spatialite_e
("gaiaDrapeLineExceptions: InitSpatialMetadata() error: %s\n",
err_msg);
sqlite3_free (err_msg);
goto end;
}
/* creating the helper tables on the Temporary MemoryDB */
if (!do_create_points (mem_db, "points1"))
goto end;
if (!do_create_points (mem_db, "points2"))
goto end;
/* populating the Points-2 helper table */
if (!do_populate_points2 (mem_db, geom2))
goto end;
/* draping the first line over Points-2 */
if (!do_drape_line (mem_db, geom1, tolerance))
goto end;
/* building the final MultiPoint to be returned */
geom3 =
do_reassemble_multi_point (mem_db, geom2->DimensionModel, geom2->Srid,
interpolated);
end:
/* releasing the Temporary MemoryDB */
ret = sqlite3_close (mem_db);
if (ret != SQLITE_OK)
spatialite_e ("gaiaDrapeLineExceptions: sqlite3_close() error: %s\n",
sqlite3_errmsg (mem_db));
spatialite_internal_cleanup (cache);
return geom3;
}
libspatialite-5.1.0/src/gaiageo/gg_endian.c 0000644 0001750 0001750 00000042255 14463127014 015540 0000000 0000000 /*
gg_endian.c -- Gaia functions for litte/big endian values handling
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
GAIAGEO_DECLARE int
gaiaEndianArch ()
{
/* checking if target CPU is a little-endian one */
union cvt
{
unsigned char byte[4];
int int_value;
} convert;
convert.int_value = 1;
if (convert.byte[0] == 0)
return 0;
return 1;
}
GAIAGEO_DECLARE short
gaiaImport16 (const unsigned char *p, int little_endian, int little_endian_arch)
{
/* fetches a 16bit int from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[2];
short short_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 1);
convert.byte[1] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 1);
convert.byte[1] = *(p + 0);
}
}
return convert.short_value;
}
GAIAGEO_DECLARE int
gaiaImport32 (const unsigned char *p, int little_endian, int little_endian_arch)
{
/* fetches a 32bit int from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
int int_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
}
return convert.int_value;
}
GAIAGEO_DECLARE unsigned int
gaiaImportU32 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches a 32bit uint from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
unsigned int int_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
}
return convert.int_value;
}
GAIAGEO_DECLARE float
gaiaImportF32 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches a 32bit float from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
float flt_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 3);
convert.byte[1] = *(p + 2);
convert.byte[2] = *(p + 1);
convert.byte[3] = *(p + 0);
}
}
return convert.flt_value;
}
GAIAGEO_DECLARE double
gaiaImport64 (const unsigned char *p, int little_endian, int little_endian_arch)
{
/* fetches a 64bit double from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[8];
double double_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 7);
convert.byte[1] = *(p + 6);
convert.byte[2] = *(p + 5);
convert.byte[3] = *(p + 4);
convert.byte[4] = *(p + 3);
convert.byte[5] = *(p + 2);
convert.byte[6] = *(p + 1);
convert.byte[7] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
convert.byte[4] = *(p + 4);
convert.byte[5] = *(p + 5);
convert.byte[6] = *(p + 6);
convert.byte[7] = *(p + 7);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
convert.byte[4] = *(p + 4);
convert.byte[5] = *(p + 5);
convert.byte[6] = *(p + 6);
convert.byte[7] = *(p + 7);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 7);
convert.byte[1] = *(p + 6);
convert.byte[2] = *(p + 5);
convert.byte[3] = *(p + 4);
convert.byte[4] = *(p + 3);
convert.byte[5] = *(p + 2);
convert.byte[6] = *(p + 1);
convert.byte[7] = *(p + 0);
}
}
return convert.double_value;
}
GAIAGEO_DECLARE sqlite3_int64
gaiaImportI64 (const unsigned char *p, int little_endian,
int little_endian_arch)
{
/* fetches a 64bit INT from BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[8];
sqlite3_int64 int64_value;
} convert;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 7);
convert.byte[1] = *(p + 6);
convert.byte[2] = *(p + 5);
convert.byte[3] = *(p + 4);
convert.byte[4] = *(p + 3);
convert.byte[5] = *(p + 2);
convert.byte[6] = *(p + 1);
convert.byte[7] = *(p + 0);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
convert.byte[4] = *(p + 4);
convert.byte[5] = *(p + 5);
convert.byte[6] = *(p + 6);
convert.byte[7] = *(p + 7);
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
convert.byte[0] = *(p + 0);
convert.byte[1] = *(p + 1);
convert.byte[2] = *(p + 2);
convert.byte[3] = *(p + 3);
convert.byte[4] = *(p + 4);
convert.byte[5] = *(p + 5);
convert.byte[6] = *(p + 6);
convert.byte[7] = *(p + 7);
}
else
{
/* Little Endian data */
convert.byte[0] = *(p + 7);
convert.byte[1] = *(p + 6);
convert.byte[2] = *(p + 5);
convert.byte[3] = *(p + 4);
convert.byte[4] = *(p + 3);
convert.byte[5] = *(p + 2);
convert.byte[6] = *(p + 1);
convert.byte[7] = *(p + 0);
}
}
return convert.int64_value;
}
GAIAGEO_DECLARE void
gaiaExport16 (unsigned char *p, short value, int little_endian,
int little_endian_arch)
{
/* stores a 16bit int into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[2];
short short_value;
} convert;
convert.short_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 1) = convert.byte[1];
*(p + 0) = convert.byte[0];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
}
else
{
/* Little Endian data */
*(p + 1) = convert.byte[0];
*(p + 0) = convert.byte[1];
}
}
}
GAIAGEO_DECLARE void
gaiaExport32 (unsigned char *p, int value, int little_endian,
int little_endian_arch)
{
/* stores a 32bit int into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
int int_value;
} convert;
convert.int_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
}
}
GAIAGEO_DECLARE void
gaiaExportU32 (unsigned char *p, unsigned int value, int little_endian,
int little_endian_arch)
{
/* stores a 32bit int into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
unsigned int int_value;
} convert;
convert.int_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
}
}
GAIAGEO_DECLARE void
gaiaExportF32 (unsigned char *p, float value, int little_endian,
int little_endian_arch)
{
/* stores a 32bit float into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[4];
float flt_value;
} convert;
convert.flt_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
}
else
{
/* Little Endian data */
*(p + 3) = convert.byte[0];
*(p + 2) = convert.byte[1];
*(p + 1) = convert.byte[2];
*(p + 0) = convert.byte[3];
}
}
}
GAIAGEO_DECLARE void
gaiaExport64 (unsigned char *p, double value, int little_endian,
int little_endian_arch)
{
/* stores a 64bit double into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[8];
double double_value;
} convert;
convert.double_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 7) = convert.byte[0];
*(p + 6) = convert.byte[1];
*(p + 5) = convert.byte[2];
*(p + 4) = convert.byte[3];
*(p + 3) = convert.byte[4];
*(p + 2) = convert.byte[5];
*(p + 1) = convert.byte[6];
*(p + 0) = convert.byte[7];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
*(p + 4) = convert.byte[4];
*(p + 5) = convert.byte[5];
*(p + 6) = convert.byte[6];
*(p + 7) = convert.byte[7];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
*(p + 4) = convert.byte[4];
*(p + 5) = convert.byte[5];
*(p + 6) = convert.byte[6];
*(p + 7) = convert.byte[7];
}
else
{
/* Little Endian data */
*(p + 7) = convert.byte[0];
*(p + 6) = convert.byte[1];
*(p + 5) = convert.byte[2];
*(p + 4) = convert.byte[3];
*(p + 3) = convert.byte[4];
*(p + 2) = convert.byte[5];
*(p + 1) = convert.byte[6];
*(p + 0) = convert.byte[7];
}
}
}
GAIAGEO_DECLARE void
gaiaExportI64 (unsigned char *p, sqlite3_int64 value, int little_endian,
int little_endian_arch)
{
/* stores a 64bit INT into a BLOB respecting declared endiannes */
union cvt
{
unsigned char byte[8];
sqlite3_int64 int64_value;
} convert;
convert.int64_value = value;
if (little_endian_arch)
{
/* Litte-Endian architecture [e.g. x86] */
if (!little_endian)
{
/* Big Endian data */
*(p + 7) = convert.byte[0];
*(p + 6) = convert.byte[1];
*(p + 5) = convert.byte[2];
*(p + 4) = convert.byte[3];
*(p + 3) = convert.byte[4];
*(p + 2) = convert.byte[5];
*(p + 1) = convert.byte[6];
*(p + 0) = convert.byte[7];
}
else
{
/* Little Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
*(p + 4) = convert.byte[4];
*(p + 5) = convert.byte[5];
*(p + 6) = convert.byte[6];
*(p + 7) = convert.byte[7];
}
}
else
{
/* Big Endian architecture [e.g. PPC] */
if (!little_endian)
{
/* Big Endian data */
*(p + 0) = convert.byte[0];
*(p + 1) = convert.byte[1];
*(p + 2) = convert.byte[2];
*(p + 3) = convert.byte[3];
*(p + 4) = convert.byte[4];
*(p + 5) = convert.byte[5];
*(p + 6) = convert.byte[6];
*(p + 7) = convert.byte[7];
}
else
{
/* Little Endian data */
*(p + 7) = convert.byte[0];
*(p + 6) = convert.byte[1];
*(p + 5) = convert.byte[2];
*(p + 4) = convert.byte[3];
*(p + 3) = convert.byte[4];
*(p + 2) = convert.byte[5];
*(p + 1) = convert.byte[6];
*(p + 0) = convert.byte[7];
}
}
}
libspatialite-5.1.0/src/gaiageo/gg_geodesic.c 0000644 0001750 0001750 00000052230 14463127014 016056 0000000 0000000 /*
gg_geodesic.c -- Gaia functions for geodesic calculations
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Charles Karney
Mark Johnson
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#include
#ifndef OMIT_PROJ
#ifdef PROJ_NEW /* supporting PROJ.6 */
#include
#define PROJ_GEODESIC 1
#include
#else /* supporting old PROJ.4 */
#include
#if defined(PJ_VERSION) && PJ_VERSION >= 490
/* Enable new proj.4's geodesic distance */
#define PROJ_GEODESIC 1
#include
#else
/* Use the old (Vincenty) geodesic distance */
#define PROJ_GEODESIC 0
#endif
#endif
#else
#define PROJ_GEODESIC 0
#endif
#define DEG2RAD 0.0174532925199432958
#define PI 3.14159265358979323846
struct ellipses
{
char *name;
double a; /* equatorial radius - meters */
double rf; /* reverse flattening */
double b; /* polar radius - meters */
};
GAIAGEO_DECLARE int
gaiaEllipseParams (const char *name, double *a, double *b, double *rf)
{
/* trying to find ellipse params */
struct ellipses ellps_list[] = {
{"MERIT", 6378137.0, 298.257, -1.0},
{"SGS85", 6378136.0, 298.257, -1.0},
{"GRS80", 6378137.0, 298.257222101, -1.0},
{"IAU76", 6378140.0, 298.257, -1.0},
{"airy", 6377563.396, -1.0, 6356256.910},
{"APL4.9", 6378137.0, 298.25, -1.0},
{"NWL9D", 6378145.0, 298.25, -1.0},
{"mod_airy", 6377340.189, -1.0, 6356034.446},
{"andrae", 6377104.43, 300.0, -1.0},
{"aust_SA", 378160.0, 298.25, -1.0},
{"GRS67", 6378160.0, 298.2471674270, -1.0},
{"bessel", 6377397.155, 299.1528128, -1.0},
{"bess_nam", 6377483.865, 299.1528128, -1.0},
{"clrk66", 6378206.4, -1.0, 6356583.8},
{"clrk80", 6378249.145, 293.4663, -1.0},
{"CPM", 6375738.7, 334.29, -1.0},
{"delmbr", 6376428.0, 311.5, -1.0},
{"engelis", 6378136.05, 298.2566, -1.0},
{"evrst30", 6377276.345, 300.8017, -1.0},
{"evrst48", 6377304.063, 300.8017, -1.0},
{"evrst56", 6377301.243, 300.8017, -1.0},
{"evrst69", 6377295.664, 300.8017, -1.0},
{"evrstSS", 6377298.556, 300.8017, -1.0},
{"fschr60", 6378166.0, 298.3, -1.0},
{"fschr60m", 6378155.0, 298.3, -1.0},
{"fschr68", 6378150.0, 298.3, -1.0},
{"helmert", 6378200.0, 298.3, -1.0},
{"hough", 6378270.0, 297.0, -1.0},
{"intl", 6378388.0, 297.0, -1.0},
{"krass", 6378245.0, 298.3, -1.0},
{"kaula", 6378163.0, 298.24, -1.0},
{"lerch", 6378139.0, 298.257, -1.0},
{"mprts", 6397300.0, 191.0, -1.0},
{"new_intl", 6378157.5, -1.0, 6356772.2},
{"plessis", 6376523.0, -1.0, 6355863.0},
{"SEasia", 6378155.0, -1.0, 6356773.3205},
{"walbeck", 6376896.0, -1.0, 6355834.8467},
{"WGS60", 6378165.0, 298.3, -1.0},
{"WGS66", 6378145.0, 298.25, -1.0},
{"WGS72", 6378135.0, 298.26, -1.0},
{"WGS84", 6378137.0, 298.257223563, -1.0},
{"sphere", 6370997.0, -1.0, 6370997.0},
{NULL, -1.0, -1.0, -1.0}
};
struct ellipses *pe = ellps_list;
while (1)
{
if (pe->name == NULL)
break;
if (strcmp (pe->name, name) == 0)
{
*a = pe->a;
if (pe->rf < 0.0)
{
*b = pe->b;
*rf = 1.0 / ((pe->a - pe->b) / pe->a);
}
else
{
*b = (pe->a * (1.0 - (1.0 / pe->rf)));
*rf = pe->rf;
}
return 1;
}
pe++;
}
return 0;
}
GAIAGEO_DECLARE double
gaiaGreatCircleDistance (double a, double b, double lat1, double lon1,
double lat2, double lon2)
{
/*
/ Calculate great-circle distance (in m) between two points specified by
/ latitude/longitude (in decimal degrees) using Aviation Formulary
/
/ http://williams.best.vwh.net/avform.htm#Dist
/
*/
double latrad1 = lat1 * DEG2RAD;
double lonrad1 = lon1 * DEG2RAD;
double latrad2 = lat2 * DEG2RAD;
double lonrad2 = lon2 * DEG2RAD;
double avg_radius;
double k1 = (sin ((latrad1 - latrad2) / 2.0));
double k2 = (sin ((lonrad1 - lonrad2) / 2.0));
double dist;
dist =
2.0 * asin (sqrt (k1 * k1 + cos (latrad1) * cos (latrad2) * k2 * k2));
if (dist < 0.0)
dist = dist + PI;
if (a == b)
avg_radius = a;
else
avg_radius = (2.0 * a + b) / 3.0;
dist = dist * avg_radius;
return dist;
}
GAIAGEO_DECLARE double
gaiaGeodesicDistance (double a, double b, double rf, double lat1, double lon1,
double lat2, double lon2)
{
/*
/ Calculate geodesic distance (in m)
/ between two points specified by latitude/longitude
/ (in decimal degrees)
*/
#if PROJ_GEODESIC
/*
/ using the PROJ.4 own implementation
/
/ requires PROJ.4 >= 4.9.0
/
/ (accepting a patch suggested by Charles Karney
*/
double s12;
struct geod_geodesic gd;
if (b == a)
b = a; /* silencing stupid compiler warnings */
geod_init (&gd, a, 1 / rf);
geod_inverse (&gd, lat1, lon1, lat2, lon2, &s12, 0, 0);
return s12;
#else
/*
/ using Vincenty inverse formula for ellipsoids
/
/ based on original JavaScript by (c) Chris Veness 2002-2008
/ http://www.movable-type.co.uk/scripts/latlong-vincenty.html
/
*/
double f = 1.0 / rf;
double L = (lon2 - lon1) * DEG2RAD;
double U1 = atan ((1.0 - f) * tan (lat1 * DEG2RAD));
double U2 = atan ((1.0 - f) * tan (lat2 * DEG2RAD));
double sinU1 = sin (U1);
double cosU1 = cos (U1);
double sinU2 = sin (U2);
double cosU2 = cos (U2);
double lambda = L;
double lambdaP;
double sinLambda;
double cosLambda;
double sinSigma;
double cosSigma;
double sigma;
double sinAlpha;
double cosSqAlpha;
double cos2SigmaM;
double C;
double uSq;
double A;
double B;
double deltaSigma;
double s;
int iterLimit = 100;
do
{
sinLambda = sin (lambda);
cosLambda = cos (lambda);
sinSigma =
sqrt ((cosU2 * sinLambda) * (cosU2 * sinLambda) +
(cosU1 * sinU2 -
sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 -
sinU1 * cosU2 * cosLambda));
if (sinSigma == 0.0)
return 0.0; /* co-incident points */
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = atan2 (sinSigma, cosSigma);
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
cos2SigmaM = cosSigma - 2.0 * sinU1 * sinU2 / cosSqAlpha;
if (isnan (cos2SigmaM))
cos2SigmaM = 0; /* equatorial line */
C = f / 16.0 * cosSqAlpha * (4.0 + f * (4.0 - 3.0 * cosSqAlpha));
lambdaP = lambda;
lambda =
L + (1.0 - C) * f * sinAlpha * (sigma +
C * sinSigma * (cos2SigmaM +
C * cosSigma *
(-1.0 +
2.0 *
cos2SigmaM *
cos2SigmaM)));
}
while (fabs (lambda - lambdaP) > 1e-12 && --iterLimit > 0);
if (iterLimit == 0)
return -1.0; /* formula failed to converge */
uSq = cosSqAlpha * (a * a - b * b) / (b * b);
A = 1.0 + uSq / 16384.0 * (4096.0 +
uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
B = uSq / 1024.0 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));
deltaSigma =
B * sinSigma * (cos2SigmaM +
B / 4.0 * (cosSigma *
(-1.0 + 2.0 * cos2SigmaM * cos2SigmaM) -
B / 6.0 * cos2SigmaM * (-3.0 +
4.0 * sinSigma *
sinSigma) * (-3.0 +
4.0 *
cos2SigmaM
*
cos2SigmaM)));
s = b * A * (sigma - deltaSigma);
return s;
#endif /* end Vincenty formula */
}
GAIAGEO_DECLARE void
gaiaFree (void *ptr)
{
/* freeing a generic memory allocation */
if (!ptr)
return;
free (ptr);
}
GAIAGEO_DECLARE double
gaiaGreatCircleTotalLength (double a, double b, int dims, double *coords,
int vert)
{
/* computing the GreatCircle total length for some Linestring/Ring */
int iv;
double x1 = 0.0;
double y1 = 0.0;
double x2;
double y2;
double z;
double m;
double len = 0.0;
for (iv = 0; iv < vert; iv++)
{
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv, &x2, &y2, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv, &x2, &y2, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv, &x2, &y2, &z, &m);
}
else
{
gaiaGetPoint (coords, iv, &x2, &y2);
}
if (iv > 0)
len += gaiaGreatCircleDistance (a, b, y1, x1, y2, x2);
x1 = x2;
y1 = y2;
}
return len;
}
GAIAGEO_DECLARE double
gaiaGeodesicTotalLength (double a, double b, double rf, int dims,
double *coords, int vert)
{
/* computing the Geodesic total length for some Linestring/Ring */
int iv;
double x1 = 0.0;
double y1 = 0.0;
double x2;
double y2;
double z;
double m;
double l;
double len = 0.0;
for (iv = 0; iv < vert; iv++)
{
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv, &x2, &y2, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv, &x2, &y2, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv, &x2, &y2, &z, &m);
}
else
{
gaiaGetPoint (coords, iv, &x2, &y2);
}
if (iv > 0)
{
l = gaiaGeodesicDistance (a, b, rf, y1, x1, y2, x2);
if (l < 0.0)
return -1.0;
len += l;
}
x1 = x2;
y1 = y2;
}
return len;
}
static int
auxGeodesicArcLength (double a, double rf, double lat1, double lon1,
double lat2, double lon2, double *parc_length_degrees,
double *parc_length_meters, double *pchord_degrees,
double *pchord_meters, double *pcentral_angle_radian,
double *pcentral_angle_degrees,
double *psegment_area_meters,
double *psegment_height_meters)
{
/*
/ practical implementation of GeodesicArcLen
/
/ *******************************************************************
/ this code was kindly contributed by Mark Johnson
/
*/
#if PROJ_GEODESIC
struct geod_geodesic gd;
double arc_length_degrees = 0.0; /* Arc Length = θ × r (when θ is in radians) */
double arc_length_meters = 0.0; /* Distance of Arc Length in meters between points 1 and 2 */
double chord_degrees = 0.0; /* Distance in Degrees of shortest Line (chord) between points 1 and 2 */
double chord_meters = 0.0; /* Distance in Meters of shortest Line (chord) between points 1 and 2 */
double central_angle_radian = 0.0; /* θ: Arc Length / r (where θ is in radians) */
double central_angle_degrees = 0.0; /* θ: Arc Length / r (where θ is in degrees) */
double segment_area_meters = 0.0; // Area of segment/arc in meters */
double segment_height_meters = 0.0; /* Height of segment/arc [short-sagitta] in meters */
double a2 = (a * a); /* pow(a,2) Radius (a) in meters */
geod_init (&gd, a, 1 / rf);
arc_length_degrees =
geod_geninverse (&gd, lat1, lon1, lat2, lon2, &arc_length_meters, 0, 0,
0, 0, 0, 0);
central_angle_radian = arc_length_meters / a; /* Central Angle [radians] from Arch Length in meters and Radius (a) in meters */
central_angle_degrees = central_angle_radian * (180 / PI); /* Central Angle [degrees] from Arch Length in meters and Radius (a) in meters */
chord_degrees = sqrt (((lat1 - lat2) * (lat1 - lat2)) + ((lon1 - lon2) * (lon1 - lon2))); /* Pythagoras Theorem */
chord_meters = sqrt ((a2 + a2) - (2 * (a2) * cos (central_angle_radian))); /* Cosine rule using Central Angle [radians] */
segment_height_meters = a - sqrt (a2 - pow ((chord_meters / 2), 2)); /* Height of Segment/Arch [short-sagitta] in meters with Radius (a) and chord in meters */
segment_area_meters = ((central_angle_radian - sin (central_angle_radian)) / 2) * a2; /* Area of Segment in meters with Radius (a) in meters */
if (parc_length_degrees)
{
*parc_length_degrees = arc_length_degrees;
}
if (parc_length_meters)
{
*parc_length_meters = arc_length_meters;
}
if (pchord_degrees)
{
*pchord_degrees = chord_degrees;
}
if (pchord_meters)
{
*pchord_meters = chord_meters;
}
if (pcentral_angle_radian)
{
*pcentral_angle_radian = central_angle_radian;
}
if (pcentral_angle_degrees)
{
*pcentral_angle_degrees = central_angle_degrees;
}
if (psegment_area_meters)
{
*psegment_area_meters = segment_area_meters;
}
if (psegment_height_meters)
{
*psegment_height_meters = segment_height_meters;
}
if ((arc_length_degrees < 0.0) || (arc_length_degrees > 180.0))
{
return 0;
}
return 1;
#else
return 0;
#endif
}
GAIAGEO_DECLARE int
gaiaGeodesicArcLength (sqlite3 * sqlite, const void *data,
gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
int return_type, double *retval)
{
/*
/ Computes several Geodesic values based on the Distance between two Geometries
/
/ *******************************************************************
/ this code was kindly contributed by Mark Johnson
/
*/
int is_longlat;
double a;
double b;
double rf;
int ret;
gaiaGeomCollPtr shortest = NULL;
#ifdef OMIT_GEOS /* not including GEOS */
gaiaPointPtr pt1;
gaiaPointPtr pt2;
gaiaLinestringPtr ln_build;
#endif
gaiaLinestringPtr ln;
double x0;
double y0;
double x1;
double y1;
double z;
double m;
double arc_length_degrees = 0.0; /* Arc Length = θ × r (when θ is in radians) */
double arc_length_meters = 0.0; /* Distance of Arc Length in meters between points 1 and 2 */
double chord_degrees = 0.0; /* Distance in Degrees of shortest Line (chord) between points 1 and 2 */
double chord_meters = 0.0; /* Distance in Meters of shortest Line (chord) between points 1 and 2 */
double central_angle_radian = 0.0; /* θ: Arc Length / r (where θ is in radians) */
double central_angle_degrees = 0.0; /* θ: Arc Length / r (where θ is in degrees) */
double segment_area_meters = 0.0; /* Area of segment/arc in meters */
double segment_height_meters = 0.0; /* Height of segment/arc [short-sagitta] in meters */
/* preliminary checks */
if (geom1 == NULL || geom2 == NULL)
return 0;
if (geom1->Srid != geom2->Srid)
return 0;
if (!srid_is_geographic (sqlite, geom1->Srid, &is_longlat))
return 0;
else if (!is_longlat)
return 0;
#ifdef OMIT_GEOS /* not including GEOS */
if (geom1->FirstLinestring != NULL || geom1->FirstPolygon != NULL
|| geom2->FirstLinestring != NULL || geom2->FirstPolygon != NULL)
return 0;
if (geom1->FirstPoint == NULL || geom1->FirstPoint != geom1->LastPoint ||
geom2->FirstPoint == NULL || geom2->FirstPoint != geom2->LastPoint)
return 0;
#endif
/* attempting to identify the corresponding ellipsoid */
if (!getEllipsoidParams (sqlite, geom1->Srid, &a, &b, &rf))
return 0;
#ifndef OMIT_GEOS /* only if GEOS is supported */
/* checking first if an intersection exists */
if (data != NULL)
ret = gaiaGeomCollIntersects_r (data, geom1, geom2);
else
ret = gaiaGeomCollIntersects (geom1, geom2);
if (ret)
{
/* if an intersection exists the distance is always ZERO */
*retval = 0.0;
return 1;
}
/* With GEOS: create a single LINESTRING with the 2 points containing the nearst point from each geometry */
if (data != NULL)
shortest = gaiaShortestLine_r (data, geom1, geom2);
else
shortest = gaiaShortestLine (geom1, geom2);
#else
pt1 = geom1->FirstPoint;
pt2 = geom2->FirstPoint;
if (pt1->X == pt2->X && pt1->Y == pt2->Y)
{
/* The Points are the same, the distance is always ZERO */
*retval = 0.0;
return 1;
}
/* Without GEOS: create a single, XY based LINESTRING with the 2 points */
shortest = gaiaAllocGeomColl ();
ln_build = gaiaAddLinestringToGeomColl (shortest, 2);
shortest->Srid = geom1->Srid;
shortest->DeclaredType = GAIA_LINESTRING;
shortest->DimensionModel = GAIA_XY;
gaiaSetPoint (ln_build->Coords, 0, pt1->X, pt1->Y);
gaiaSetPoint (ln_build->Coords, 1, pt2->X, pt2->Y);
#endif
if (shortest == NULL)
return 0;
else if (shortest->FirstLinestring == NULL)
{
gaiaFreeGeomColl (shortest);
return 0;
}
ln = shortest->FirstLinestring;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, 0, &x0, &y0, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, 0, &x0, &y0, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, 0, &x0, &y0, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, 0, &x0, &y0);
}
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, 1, &x1, &y1, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, 1, &x1, &y1, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, 1, &x1, &y1, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, 1, &x1, &y1);
}
if (auxGeodesicArcLength
(a, rf, y0, x0, y1, x1, &arc_length_degrees, &arc_length_meters,
&chord_degrees, &chord_meters, ¢ral_angle_radian,
¢ral_angle_degrees, &segment_area_meters, &segment_height_meters))
{
switch (return_type)
{
case GAIA_GEODESIC_ARC_LENGTH_METERS:
/*: arc_length_meters as Distance of Arc Length in meters between points 1 and 2 */
*retval = arc_length_meters;
break;
case GAIA_GEODESIC_CHORD_LENGTH_DEGREES:
/* chord_degrees as Distance in Degrees of shortest Line (chord) between points 1 and 2 */
*retval = chord_degrees;
break;
case GAIA_GEODESIC_CHORD_LENGTH_METERS:
/* chord_meters as Distance in Meters of shortest Line (chord) between points 1 and 2 */
*retval = chord_meters;
break;
case GAIA_GEODESIC_CENTRAL_ANGLE_RADIANS:
/* central_angle_radian , as radians, from Arch Length in meters and Radius (a) in meters */
*retval = central_angle_radian;
break;
case GAIA_GEODESIC_CENTRAL_ANGLE_DEGREES:
/* central_angle_degrees, as degrees, from Arch Length in meters and Radius (a) in meters */
*retval = central_angle_degrees;
break;
case GAIA_GEODESIC_ARC_AREA_METERS:
/* segment_area_meters, Area of segment/arc in meters */
*retval = segment_area_meters;
break;
case GAIA_GEODESIC_ARC_HEIGHT_METERS:
/* segment_height_meters, in meters, Height of segment/arc [short-sagitta] in meters */
*retval = segment_height_meters;
break;
case GAIA_GEODESIC_ARC_LENGTH_DEGREES:
default:
/* arc_length_degrees as Distance of Arc Length in degrees between points 1 and 2 */
*retval = arc_length_degrees;
break;
}
gaiaFreeGeomColl (shortest);
return 1;
}
/* invalid distance (for Arc-Length in degrees not between 0-180) */
gaiaFreeGeomColl (shortest);
return 0;
}
GAIAGEO_DECLARE int
gaiaConvertLength (double value, int unit_from, int unit_to, double *cvt)
{
/* converting length from one unit to another */
double m;
double factors[] = {
1000.0, 1.0, 0.1, 0.01, 0.001, 1852.0, 0.0254, 0.3048, 0.9144,
1609.344, 1.8288, 20.1168, 0.201168, 1.0, 0.304800609601219,
0.914401828803658, 20.11684023368047, 1609.347218694437, 0.91439523,
0.30479841, 20.11669506
};
factors[GAIA_US_IN] /= 39.37;
if (unit_from < GAIA_MIN_UNIT || unit_from > GAIA_MAX_UNIT)
return 0;
if (unit_to < GAIA_MIN_UNIT || unit_to > GAIA_MAX_UNIT)
return 0;
if (unit_from == unit_to)
{
/* same unit */
*cvt = value;
}
else if (unit_from == GAIA_M)
{
/* from Meters to .. */
*cvt = value / factors[unit_to];
}
else if (unit_to == GAIA_M)
{
/* from .. to Meters */
*cvt = value * factors[unit_from];
}
else
{
m = value * factors[unit_from];
*cvt = m / factors[unit_to];
}
return 1;
}
#undef DEG2RAD
#undef PI
libspatialite-5.1.0/src/gaiageo/gg_geometries.c 0000644 0001750 0001750 00000432423 14463127014 016445 0000000 0000000 /*
gg_geometries.c -- Gaia geometric objects
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
GAIAGEO_DECLARE gaiaPointPtr
gaiaAllocPoint (double x, double y)
{
/* POINT object constructor */
gaiaPointPtr p = malloc (sizeof (gaiaPoint));
p->X = x;
p->Y = y;
p->Z = 0.0;
p->M = 0.0;
p->DimensionModel = GAIA_XY;
p->Next = NULL;
p->Prev = NULL;
return p;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAllocPointXYZ (double x, double y, double z)
{
/* POINT object constructor */
gaiaPointPtr p = malloc (sizeof (gaiaPoint));
p->X = x;
p->Y = y;
p->Z = z;
p->M = 0.0;
p->DimensionModel = GAIA_XY_Z;
p->Next = NULL;
p->Prev = NULL;
return p;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAllocPointXYM (double x, double y, double m)
{
/* POINT object constructor */
gaiaPointPtr p = malloc (sizeof (gaiaPoint));
p->X = x;
p->Y = y;
p->Z = 0.0;
p->M = m;
p->DimensionModel = GAIA_XY_M;
p->Next = NULL;
p->Prev = NULL;
return p;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAllocPointXYZM (double x, double y, double z, double m)
{
/* POINT object constructor */
gaiaPointPtr p = malloc (sizeof (gaiaPoint));
p->X = x;
p->Y = y;
p->Z = z;
p->M = m;
p->DimensionModel = GAIA_XY_Z_M;
p->Next = NULL;
p->Prev = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreePoint (gaiaPointPtr ptr)
{
/* POINT object destructor */
if (ptr != NULL)
free (ptr);
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAllocLinestring (int vert)
{
/* LINESTRING object constructor */
gaiaLinestringPtr p = malloc (sizeof (gaiaLinestring));
p->Coords = malloc (sizeof (double) * (vert * 2));
p->Points = vert;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAllocLinestringXYZ (int vert)
{
/* LINESTRING object constructor */
gaiaLinestringPtr p = malloc (sizeof (gaiaLinestring));
p->Coords = malloc (sizeof (double) * (vert * 3));
p->Points = vert;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAllocLinestringXYM (int vert)
{
/* LINESTRING object constructor */
gaiaLinestringPtr p = malloc (sizeof (gaiaLinestring));
p->Coords = malloc (sizeof (double) * (vert * 3));
p->Points = vert;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_M;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAllocLinestringXYZM (int vert)
{
/* LINESTRING object constructor */
gaiaLinestringPtr p = malloc (sizeof (gaiaLinestring));
p->Coords = malloc (sizeof (double) * (vert * 4));
p->Points = vert;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z_M;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreeLinestring (gaiaLinestringPtr ptr)
{
/* LINESTRING object desctructror */
if (ptr)
{
if (ptr->Coords)
free (ptr->Coords);
free (ptr);
}
}
GAIAGEO_DECLARE int
gaiaLineGetPoint (gaiaLinestringPtr ln, int v, double *x, double *y, double *z,
double *m)
{
/* SAFE - getting coords for a vertex in LINESTRING */
double vx;
double vy;
double vz;
double vm;
*x = 0.0;
*y = 0.0;
*z = 0.0;
*m = 0.0;
if (!ln)
return 0;
if (v < 0 || v >= ln->Points)
return 0;
switch (ln->DimensionModel)
{
case GAIA_XY:
gaiaGetPoint (ln->Coords, v, &vx, &vy);
*x = vx;
*y = vy;
break;
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, v, &vx, &vy, &vz);
*x = vx;
*y = vy;
*z = vz;
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, v, &vx, &vy, &vm);
*x = vx;
*y = vy;
*m = vm;
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, v, &vx, &vy, &vz, &vm);
*x = vx;
*y = vy;
*z = vz;
*m = vm;
break;
default:
return 0;
};
return 1;
}
GAIAGEO_DECLARE int
gaiaLineSetPoint (gaiaLinestringPtr ln, int v, double x, double y, double z,
double m)
{
/* SAFE - setting coords for a vertex in RING */
if (!ln)
return 0;
if (v < 0 || v >= ln->Points)
return 0;
switch (ln->DimensionModel)
{
case GAIA_XY:
gaiaSetPoint (ln->Coords, v, x, y);
break;
case GAIA_XY_Z:
gaiaSetPointXYZ (ln->Coords, v, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (ln->Coords, v, x, y, m);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (ln->Coords, v, x, y, z, m);
break;
default:
return 0;
};
return 1;
}
GAIAGEO_DECLARE void
gaiaCopyLinestringCoords (gaiaLinestringPtr dst, gaiaLinestringPtr src)
{
/*
/ copying coords from one Linestring to another
/ maybe, converting from one Dimension Model to a different one
*/
gaiaCopyLinestringCoordsEx (dst, src, 0.0, 0.0);
}
GAIAGEO_DECLARE void
gaiaCopyLinestringCoordsEx (gaiaLinestringPtr dst, gaiaLinestringPtr src,
double z_no_data, double m_no_data)
{
/*
/ copying coords from one Linestring to another
/ maybe, converting from one Dimension Model to a different one
*/
int iv;
double x;
double y;
double z;
double m;
if (!src)
return;
if (!dst)
return;
if (src->Points != dst->Points)
return;
for (iv = 0; iv < dst->Points; iv++)
{
z = z_no_data;
m = m_no_data;
if (src->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (src->Coords, iv, &x, &y, &z);
}
else if (src->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (src->Coords, iv, &x, &y, &m);
}
else if (src->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (src->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (src->Coords, iv, &x, &y);
}
if (dst->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst->Coords, iv, x, y, z);
}
else if (dst->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst->Coords, iv, x, y, m);
}
else if (dst->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (dst->Coords, iv, x, y);
}
}
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaCloneLinestring (gaiaLinestringPtr line)
{
/* clones a LINESTRING */
gaiaLinestringPtr new_line;
if (!line)
return NULL;
if (line->DimensionModel == GAIA_XY_Z)
new_line = gaiaAllocLinestringXYZ (line->Points);
else if (line->DimensionModel == GAIA_XY_M)
new_line = gaiaAllocLinestringXYM (line->Points);
else if (line->DimensionModel == GAIA_XY_Z_M)
new_line = gaiaAllocLinestringXYZM (line->Points);
else
new_line = gaiaAllocLinestring (line->Points);
gaiaCopyLinestringCoords (new_line, line);
return new_line;
}
GAIAGEO_DECLARE void
gaiaCopyLinestringCoordsReverse (gaiaLinestringPtr dst, gaiaLinestringPtr src)
{
/*
/ copying coords from one Linestring to another in reverse order
/ maybe, converting from one Dimension Model to a different one
*/
int iv;
int iv2 = 0;
double x;
double y;
double z;
double m;
if (!src)
return;
if (!dst)
return;
if (src->Points != dst->Points)
return;
for (iv = src->Points - 1; iv >= 0; iv--)
{
z = 0.0;
m = 0.0;
if (src->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (src->Coords, iv, &x, &y, &z);
}
else if (src->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (src->Coords, iv, &x, &y, &m);
}
else if (src->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (src->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (src->Coords, iv, &x, &y);
}
if (dst->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst->Coords, iv2, x, y, z);
}
else if (dst->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst->Coords, iv2, x, y, m);
}
else if (dst->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst->Coords, iv2, x, y, z, m);
}
else
{
gaiaSetPoint (dst->Coords, iv2, x, y);
}
iv2++;
}
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaCloneLinestringSpecial (gaiaLinestringPtr line, int mode)
{
/* clones a LINESTRING (special) */
gaiaLinestringPtr new_line;
if (!line)
return NULL;
if (mode != GAIA_REVERSE_ORDER)
return gaiaCloneLinestring (line);
if (line->DimensionModel == GAIA_XY_Z)
new_line = gaiaAllocLinestringXYZ (line->Points);
else if (line->DimensionModel == GAIA_XY_M)
new_line = gaiaAllocLinestringXYM (line->Points);
else if (line->DimensionModel == GAIA_XY_Z_M)
new_line = gaiaAllocLinestringXYZM (line->Points);
else
new_line = gaiaAllocLinestring (line->Points);
gaiaCopyLinestringCoordsReverse (new_line, line);
return new_line;
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaAllocRing (int vert)
{
/* ring object constructor */
gaiaRingPtr p = malloc (sizeof (gaiaRing));
p->Coords = malloc (sizeof (double) * (vert * 2));
p->Points = vert;
p->Link = NULL;
p->Clockwise = 0;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaAllocRingXYZ (int vert)
{
/* ring object constructor */
gaiaRingPtr p = malloc (sizeof (gaiaRing));
p->Coords = malloc (sizeof (double) * (vert * 3));
p->Points = vert;
p->Link = NULL;
p->Clockwise = 0;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaAllocRingXYM (int vert)
{
/* ring object constructor */
gaiaRingPtr p = malloc (sizeof (gaiaRing));
p->Coords = malloc (sizeof (double) * (vert * 3));
p->Points = vert;
p->Link = NULL;
p->Clockwise = 0;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_M;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaAllocRingXYZM (int vert)
{
/* ring object constructor */
gaiaRingPtr p = malloc (sizeof (gaiaRing));
p->Coords = malloc (sizeof (double) * (vert * 4));
p->Points = vert;
p->Link = NULL;
p->Clockwise = 0;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z_M;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreeRing (gaiaRingPtr ptr)
{
/* ring object destructor */
if (ptr)
{
if (ptr->Coords)
free (ptr->Coords);
free (ptr);
}
}
GAIAGEO_DECLARE int
gaiaRingGetPoint (gaiaRingPtr rng, int v, double *x, double *y, double *z,
double *m)
{
/* SAFE - getting coords for a vertex in RING */
double vx;
double vy;
double vz;
double vm;
*x = 0.0;
*y = 0.0;
*z = 0.0;
*m = 0.0;
if (!rng)
return 0;
if (v < 0 || v >= rng->Points)
return 0;
switch (rng->DimensionModel)
{
case GAIA_XY:
gaiaGetPoint (rng->Coords, v, &vx, &vy);
*x = vx;
*y = vy;
break;
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, v, &vx, &vy, &vz);
*x = vx;
*y = vy;
*z = vz;
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, v, &vx, &vy, &vm);
*x = vx;
*y = vy;
*m = vm;
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, v, &vx, &vy, &vz, &vm);
*x = vx;
*y = vy;
*z = vz;
*m = vm;
break;
default:
return 0;
};
return 1;
}
GAIAGEO_DECLARE int
gaiaRingSetPoint (gaiaRingPtr rng, int v, double x, double y, double z,
double m)
{
/* SAFE - getting coords for a vertex in RING */
if (!rng)
return 0;
if (v < 0 || v >= rng->Points)
return 0;
switch (rng->DimensionModel)
{
case GAIA_XY:
gaiaSetPoint (rng->Coords, v, x, y);
break;
case GAIA_XY_Z:
gaiaSetPointXYZ (rng->Coords, v, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (rng->Coords, v, x, y, m);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (rng->Coords, v, x, y, z, m);
break;
default:
return 0;
};
return 1;
}
GAIAGEO_DECLARE void
gaiaCopyRingCoords (gaiaRingPtr dst, gaiaRingPtr src)
{
/*
/ copying coords from one Ring to another
/ maybe, converting from one Dimension Model to a different one
*/
gaiaCopyRingCoordsEx (dst, src, 0.0, 0.0);
}
GAIAGEO_DECLARE void
gaiaCopyRingCoordsEx (gaiaRingPtr dst, gaiaRingPtr src, double z_no_data,
double m_no_data)
{
/*
/ copying coords from one Ring to another
/ maybe, converting from one Dimension Model to a different one
*/
int iv;
double x;
double y;
double z;
double m;
if (!src)
return;
if (!dst)
return;
if (src->Points != dst->Points)
return;
for (iv = 0; iv < dst->Points; iv++)
{
z = z_no_data;
m = m_no_data;
if (src->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (src->Coords, iv, &x, &y, &z);
}
else if (src->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (src->Coords, iv, &x, &y, &m);
}
else if (src->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (src->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (src->Coords, iv, &x, &y);
}
if (dst->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst->Coords, iv, x, y, z);
}
else if (dst->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst->Coords, iv, x, y, m);
}
else if (dst->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (dst->Coords, iv, x, y);
}
}
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaCloneRing (gaiaRingPtr ring)
{
/* clones a RING */
gaiaRingPtr new_ring;
if (!ring)
return NULL;
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);
gaiaCopyRingCoords (new_ring, ring);
return new_ring;
}
GAIAGEO_DECLARE void
gaiaCopyRingCoordsReverse (gaiaRingPtr dst, gaiaRingPtr src)
{
/*
/ copying coords from one Ring to another in reverse order
/ maybe, converting from one Dimension Model to a different one
*/
int iv;
int iv2 = 0;
double x;
double y;
double z;
double m;
if (!src)
return;
if (!dst)
return;
if (src->Points != dst->Points)
return;
for (iv = src->Points - 1; iv >= 0; iv--)
{
z = 0.0;
m = 0.0;
if (src->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (src->Coords, iv, &x, &y, &z);
}
else if (src->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (src->Coords, iv, &x, &y, &m);
}
else if (src->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (src->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (src->Coords, iv, &x, &y);
}
if (dst->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst->Coords, iv2, x, y, z);
}
else if (dst->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst->Coords, iv2, x, y, m);
}
else if (dst->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst->Coords, iv2, x, y, z, m);
}
else
{
gaiaSetPoint (dst->Coords, iv2, x, y);
}
iv2++;
}
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaCloneRingSpecial (gaiaRingPtr ring, int mode)
{
/* clones a RING (special) */
gaiaRingPtr new_ring;
if (!ring)
return NULL;
if (mode != GAIA_REVERSE_ORDER)
return gaiaCloneRing (ring);
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);
gaiaCopyRingCoordsReverse (new_ring, ring);
return new_ring;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaClonePolygon (gaiaPolygonPtr polyg)
{
/* clones a POLYGON */
int ib;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!polyg)
return NULL;
i_ring = polyg->Exterior;
if (polyg->DimensionModel == GAIA_XY_Z)
new_polyg = gaiaAllocPolygonXYZ (i_ring->Points, polyg->NumInteriors);
else if (polyg->DimensionModel == GAIA_XY_M)
new_polyg = gaiaAllocPolygonXYM (i_ring->Points, polyg->NumInteriors);
else if (polyg->DimensionModel == GAIA_XY_Z_M)
new_polyg = gaiaAllocPolygonXYZM (i_ring->Points, polyg->NumInteriors);
else
new_polyg = gaiaAllocPolygon (i_ring->Points, polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoords (o_ring, i_ring);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
return new_polyg;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaClonePolygonSpecial (gaiaPolygonPtr polyg, int mode)
{
/* clones a POLYGON (special) */
int ib;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!polyg)
return NULL;
if (mode == GAIA_REVERSE_ORDER || mode == GAIA_CW_ORDER
|| mode == GAIA_CCW_ORDER)
;
else
return gaiaClonePolygon (polyg);
i_ring = polyg->Exterior;
if (polyg->DimensionModel == GAIA_XY_Z)
new_polyg = gaiaAllocPolygonXYZ (i_ring->Points, polyg->NumInteriors);
else if (polyg->DimensionModel == GAIA_XY_M)
new_polyg = gaiaAllocPolygonXYM (i_ring->Points, polyg->NumInteriors);
else if (polyg->DimensionModel == GAIA_XY_Z_M)
new_polyg = gaiaAllocPolygonXYZM (i_ring->Points, polyg->NumInteriors);
else
new_polyg = gaiaAllocPolygon (i_ring->Points, polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
if (mode == GAIA_REVERSE_ORDER)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
{
gaiaClockwise (i_ring);
if (mode == GAIA_CCW_ORDER)
{
/* returning a Counter-Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* returning a Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoords (o_ring, i_ring);
else
gaiaCopyRingCoordsReverse (o_ring, i_ring);
}
}
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
if (mode == GAIA_REVERSE_ORDER)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
{
if (mode == GAIA_CCW_ORDER)
{
/* returning a Counter-Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoords (o_ring, i_ring);
else
gaiaCopyRingCoordsReverse (o_ring, i_ring);
}
else
{
/* returning a Clockwise Polygon */
gaiaClockwise (i_ring);
if (i_ring->Clockwise)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
gaiaCopyRingCoords (o_ring, i_ring);
}
}
}
return new_polyg;
}
GAIAGEO_DECLARE int
gaiaCheckClockwise (gaiaGeomCollPtr geom)
{
/* checking for a Clockwise Geometry */
int retval = 1;
gaiaPolygonPtr polyg;
int ib;
gaiaRingPtr i_ring;
if (!geom)
return 1;
polyg = geom->FirstPolygon;
while (polyg != NULL)
{
i_ring = polyg->Exterior;
gaiaClockwise (i_ring);
if (i_ring->Clockwise == 0)
retval = 0;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* checking each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
gaiaClockwise (i_ring);
if (i_ring->Clockwise)
retval = 0;
}
polyg = polyg->Next;
}
return retval;
}
GAIAGEO_DECLARE int
gaiaCheckCounterClockwise (gaiaGeomCollPtr geom)
{
/* checking for a CounterClockwise Geometry */
int retval = 1;
gaiaPolygonPtr polyg;
int ib;
gaiaRingPtr i_ring;
if (!geom)
return 1;
polyg = geom->FirstPolygon;
while (polyg != NULL)
{
i_ring = polyg->Exterior;
gaiaClockwise (i_ring);
if (i_ring->Clockwise)
retval = 0;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* checking each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
gaiaClockwise (i_ring);
if (i_ring->Clockwise == 0)
retval = 0;
}
polyg = polyg->Next;
}
return retval;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaAllocPolygon (int vert, int excl)
{
/* POLYGON object constructor */
gaiaPolygonPtr p;
gaiaRingPtr pP;
int ind;
p = malloc (sizeof (gaiaPolygon));
p->Exterior = gaiaAllocRing (vert);
p->NumInteriors = excl;
p->NextInterior = 0;
p->Next = NULL;
if (excl == 0)
p->Interiors = NULL;
else
p->Interiors = malloc (sizeof (gaiaRing) * excl);
for (ind = 0; ind < p->NumInteriors; ind++)
{
pP = p->Interiors + ind;
pP->Points = 0;
pP->Coords = NULL;
pP->Next = NULL;
pP->Link = 0;
}
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY;
return p;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaAllocPolygonXYZ (int vert, int excl)
{
/* POLYGON object constructor */
gaiaPolygonPtr p;
gaiaRingPtr pP;
int ind;
p = malloc (sizeof (gaiaPolygon));
p->Exterior = gaiaAllocRingXYZ (vert);
p->NumInteriors = excl;
p->NextInterior = 0;
p->Next = NULL;
if (excl == 0)
p->Interiors = NULL;
else
p->Interiors = malloc (sizeof (gaiaRing) * excl);
for (ind = 0; ind < p->NumInteriors; ind++)
{
pP = p->Interiors + ind;
pP->Points = 0;
pP->Coords = NULL;
pP->Next = NULL;
pP->Link = 0;
}
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z;
return p;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaAllocPolygonXYM (int vert, int excl)
{
/* POLYGON object constructor */
gaiaPolygonPtr p;
gaiaRingPtr pP;
int ind;
p = malloc (sizeof (gaiaPolygon));
p->Exterior = gaiaAllocRingXYM (vert);
p->NumInteriors = excl;
p->NextInterior = 0;
p->Next = NULL;
if (excl == 0)
p->Interiors = NULL;
else
p->Interiors = malloc (sizeof (gaiaRing) * excl);
for (ind = 0; ind < p->NumInteriors; ind++)
{
pP = p->Interiors + ind;
pP->Points = 0;
pP->Coords = NULL;
pP->Next = NULL;
pP->Link = 0;
}
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_M;
return p;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaAllocPolygonXYZM (int vert, int excl)
{
/* POLYGON object constructor */
gaiaPolygonPtr p;
gaiaRingPtr pP;
int ind;
p = malloc (sizeof (gaiaPolygon));
p->Exterior = gaiaAllocRingXYZM (vert);
p->NumInteriors = excl;
p->NextInterior = 0;
p->Next = NULL;
if (excl == 0)
p->Interiors = NULL;
else
p->Interiors = malloc (sizeof (gaiaRing) * excl);
for (ind = 0; ind < p->NumInteriors; ind++)
{
pP = p->Interiors + ind;
pP->Points = 0;
pP->Coords = NULL;
pP->Next = NULL;
pP->Link = 0;
}
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z_M;
return p;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaCreatePolygon (gaiaRingPtr ring)
{
/* POLYGON object constructor */
gaiaPolygonPtr p;
p = malloc (sizeof (gaiaPolygon));
p->DimensionModel = ring->DimensionModel;
if (ring->DimensionModel == GAIA_XY_Z)
p->Exterior = gaiaAllocRingXYZ (ring->Points);
else if (ring->DimensionModel == GAIA_XY_M)
p->Exterior = gaiaAllocRingXYM (ring->Points);
else if (ring->DimensionModel == GAIA_XY_Z_M)
p->Exterior = gaiaAllocRingXYZM (ring->Points);
else
p->Exterior = gaiaAllocRing (ring->Points);
p->NumInteriors = 0;
p->NextInterior = 0;
p->Next = NULL;
p->Interiors = NULL;
gaiaCopyRingCoords (p->Exterior, ring);
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
return p;
}
GAIAGEO_DECLARE void
gaiaFreePolygon (gaiaPolygonPtr p)
{
/* POLYGON object destructor */
gaiaRingPtr pP;
int ind;
if (p->Exterior)
gaiaFreeRing (p->Exterior);
for (ind = 0; ind < p->NumInteriors; ind++)
{
pP = p->Interiors + ind;
if (pP->Coords)
free (pP->Coords);
}
if (p->Interiors)
free (p->Interiors);
free (p);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomColl (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (new_geom, point->X, point->Y,
point->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom, point->X, point->Y,
point->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, point->M);
else
gaiaAddPointToGeomColl (new_geom, point->X, point->Y);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoords (o_ring, i_ring);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomCollSpecial (gaiaGeomCollPtr geom, int mode)
{
/* clones a GEOMETRYCOLLECTION (special) */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (mode == GAIA_REVERSE_ORDER || mode == GAIA_CW_ORDER
|| mode == GAIA_CCW_ORDER)
;
else
return gaiaCloneGeomColl (geom);
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (new_geom, point->X, point->Y,
point->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom, point->X, point->Y,
point->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, point->M);
else
gaiaAddPointToGeomColl (new_geom, point->X, point->Y);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
if (mode == GAIA_REVERSE_ORDER)
gaiaCopyLinestringCoordsReverse (new_line, line);
else
gaiaCopyLinestringCoords (new_line, line);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
if (mode == GAIA_REVERSE_ORDER)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
{
gaiaClockwise (i_ring);
if (mode == GAIA_CCW_ORDER)
{
/* Counter-Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
gaiaCopyRingCoords (o_ring, i_ring);
}
else
{
/* Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoords (o_ring, i_ring);
else
gaiaCopyRingCoordsReverse (o_ring, i_ring);
}
}
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
if (mode == GAIA_REVERSE_ORDER)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
{
gaiaClockwise (i_ring);
if (mode == GAIA_CCW_ORDER)
{
/* Counter-Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoords (o_ring, i_ring);
else
gaiaCopyRingCoordsReverse (o_ring, i_ring);
}
else
{
/* Clockwise Polygon */
if (i_ring->Clockwise)
gaiaCopyRingCoordsReverse (o_ring, i_ring);
else
gaiaCopyRingCoords (o_ring, i_ring);
}
}
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomCollPoints (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION (Points only) */
gaiaPointPtr point;
gaiaGeomCollPtr new_geom;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = GAIA_MULTIPOINT;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (new_geom, point->X, point->Y,
point->Z);
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom, point->X, point->Y,
point->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, point->M);
else
gaiaAddPointToGeomColl (new_geom, point->X, point->Y);
point = point->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomCollLinestrings (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION (Linestrings only) */
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr new_geom;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = GAIA_MULTILINESTRING;
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
line = line->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCloneGeomCollPolygons (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION (Polygons only) */
int ib;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
new_geom = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = GAIA_MULTIPOLYGON;
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoords (o_ring, i_ring);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXY (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION converting to XY-dimensions */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
if (!geom)
return NULL;
new_geom = gaiaAllocGeomColl ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
gaiaAddPointToGeomColl (new_geom, point->X, point->Y);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoords (new_line, line);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoords (o_ring, i_ring);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYZ (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION converting to XYZ-dimensions */
return gaiaCastGeomCollToXYZnoData (geom, 0.0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYZnoData (gaiaGeomCollPtr geom, double no_data)
{
/* clones a GEOMETRYCOLLECTION converting to XYZ-dimensions */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
int has_z = 0;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
new_geom = gaiaAllocGeomCollXYZ ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (has_z)
gaiaAddPointToGeomCollXYZ (new_geom, point->X, point->Y,
point->Z);
else
gaiaAddPointToGeomCollXYZ (new_geom, point->X, point->Y, no_data);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoordsEx (new_line, line, no_data, 0.0);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoordsEx (o_ring, i_ring, no_data, 0.0);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoordsEx (o_ring, i_ring, no_data, 0.0);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYM (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION converting to XYM-dimensions */
return gaiaCastGeomCollToXYMnoData (geom, 0.0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYMnoData (gaiaGeomCollPtr geom, double no_data)
{
/* clones a GEOMETRYCOLLECTION converting to XYM-dimensions */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
int has_m = 0;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_M
|| geom->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
new_geom = gaiaAllocGeomCollXYM ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (has_m)
gaiaAddPointToGeomCollXYM (new_geom, point->X, point->Y,
point->M);
else
gaiaAddPointToGeomCollXYM (new_geom, point->X, point->Y, no_data);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoordsEx (new_line, line, 0.0, no_data);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoordsEx (o_ring, i_ring, 0.0, no_data);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoordsEx (o_ring, i_ring, 0.0, no_data);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYZM (gaiaGeomCollPtr geom)
{
/* clones a GEOMETRYCOLLECTION converting to XYZM-dimensions */
return gaiaCastGeomCollToXYZMnoData (geom, 0.0, 0.0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCastGeomCollToXYZMnoData (gaiaGeomCollPtr geom, double z_no_data,
double m_no_data)
{
/* clones a GEOMETRYCOLLECTION converting to XYZM-dimensions */
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaLinestringPtr new_line;
gaiaPolygonPtr polyg;
gaiaPolygonPtr new_polyg;
gaiaGeomCollPtr new_geom;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
int has_z = 0;
int has_m = 0;
if (!geom)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (geom->DimensionModel == GAIA_XY_M
|| geom->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
new_geom = gaiaAllocGeomCollXYZM ();
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
point = geom->FirstPoint;
while (point)
{
/* copying POINTs */
if (has_z && has_m)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, point->M);
else if (has_z)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
point->Z, m_no_data);
else if (has_m)
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
z_no_data, point->M);
else
gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y,
z_no_data, m_no_data);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* copying LINESTRINGs */
new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points);
gaiaCopyLinestringCoordsEx (new_line, line, z_no_data, m_no_data);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* copying POLYGONs */
i_ring = polyg->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (new_geom, i_ring->Points,
polyg->NumInteriors);
o_ring = new_polyg->Exterior;
/* copying points for the EXTERIOR RING */
gaiaCopyRingCoordsEx (o_ring, i_ring, z_no_data, m_no_data);
for (ib = 0; ib < new_polyg->NumInteriors; ib++)
{
/* copying each INTERIOR RING [if any] */
i_ring = polyg->Interiors + ib;
o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points);
gaiaCopyRingCoordsEx (o_ring, i_ring, z_no_data, m_no_data);
}
polyg = polyg->Next;
}
return new_geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAllocGeomColl ()
{
/* GEOMETRYCOLLECTION object constructor */
gaiaGeomCollPtr p = malloc (sizeof (gaiaGeomColl));
p->Srid = 0;
p->endian = ' ';
p->offset = 0;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY;
p->DeclaredType = GAIA_UNKNOWN;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAllocGeomCollXYZ ()
{
/* GEOMETRYCOLLECTION object constructor */
gaiaGeomCollPtr p = malloc (sizeof (gaiaGeomColl));
p->Srid = 0;
p->endian = ' ';
p->offset = 0;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z;
p->DeclaredType = GAIA_UNKNOWN;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAllocGeomCollXYM ()
{
/* GEOMETRYCOLLECTION object constructor */
gaiaGeomCollPtr p = malloc (sizeof (gaiaGeomColl));
p->Srid = 0;
p->endian = ' ';
p->offset = 0;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_M;
p->DeclaredType = GAIA_UNKNOWN;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAllocGeomCollXYZM ()
{
/* GEOMETRYCOLLECTION object constructor */
gaiaGeomCollPtr p = malloc (sizeof (gaiaGeomColl));
p->Srid = 0;
p->endian = ' ';
p->offset = 0;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
p->MinX = DBL_MAX;
p->MinY = DBL_MAX;
p->MaxX = -DBL_MAX;
p->MaxY = -DBL_MAX;
p->DimensionModel = GAIA_XY_Z_M;
p->DeclaredType = GAIA_UNKNOWN;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreeGeomColl (gaiaGeomCollPtr p)
{
/* GEOMETRYCOLLECTION object destructor */
gaiaPointPtr pP;
gaiaPointPtr pPn;
gaiaLinestringPtr pL;
gaiaLinestringPtr pLn;
gaiaPolygonPtr pA;
gaiaPolygonPtr pAn;
if (!p)
return;
pP = p->FirstPoint;
while (pP != NULL)
{
pPn = pP->Next;
gaiaFreePoint (pP);
pP = pPn;
}
pL = p->FirstLinestring;
while (pL != NULL)
{
pLn = pL->Next;
gaiaFreeLinestring (pL);
pL = pLn;
}
pA = p->FirstPolygon;
while (pA != NULL)
{
pAn = pA->Next;
gaiaFreePolygon (pA);
pA = pAn;
}
free (p);
}
GAIAGEO_DECLARE void
gaiaAddPointToGeomColl (gaiaGeomCollPtr p, double x, double y)
{
/* adding a POINT to this GEOMETRYCOLLECTION */
gaiaPointPtr point = gaiaAllocPoint (x, y);
if (p->FirstPoint == NULL)
p->FirstPoint = point;
if (p->LastPoint != NULL)
p->LastPoint->Next = point;
p->LastPoint = point;
}
GAIAGEO_DECLARE void
gaiaAddPointToGeomCollXYZ (gaiaGeomCollPtr p, double x, double y, double z)
{
/* adding a POINT to this GEOMETRYCOLLECTION */
gaiaPointPtr point = gaiaAllocPointXYZ (x, y, z);
if (p->FirstPoint == NULL)
p->FirstPoint = point;
if (p->LastPoint != NULL)
p->LastPoint->Next = point;
p->LastPoint = point;
}
GAIAGEO_DECLARE void
gaiaAddPointToGeomCollXYM (gaiaGeomCollPtr p, double x, double y, double m)
{
/* adding a POINT to this GEOMETRYCOLLECTION */
gaiaPointPtr point = gaiaAllocPointXYM (x, y, m);
if (p->FirstPoint == NULL)
p->FirstPoint = point;
if (p->LastPoint != NULL)
p->LastPoint->Next = point;
p->LastPoint = point;
}
GAIAGEO_DECLARE void
gaiaAddPointToGeomCollXYZM (gaiaGeomCollPtr p, double x, double y, double z,
double m)
{
/* adding a POINT to this GEOMETRYCOLLECTION */
gaiaPointPtr point = gaiaAllocPointXYZM (x, y, z, m);
if (p->FirstPoint == NULL)
p->FirstPoint = point;
if (p->LastPoint != NULL)
p->LastPoint->Next = point;
p->LastPoint = point;
}
GAIAGEO_DECLARE gaiaLinestringPtr
gaiaAddLinestringToGeomColl (gaiaGeomCollPtr p, int vert)
{
/* adding a LINESTRING to this GEOMETRYCOLLECTION */
gaiaLinestringPtr line;
if (p->DimensionModel == GAIA_XY_Z)
line = gaiaAllocLinestringXYZ (vert);
else if (p->DimensionModel == GAIA_XY_M)
line = gaiaAllocLinestringXYM (vert);
else if (p->DimensionModel == GAIA_XY_Z_M)
line = gaiaAllocLinestringXYZM (vert);
else
line = gaiaAllocLinestring (vert);
if (p->FirstLinestring == NULL)
p->FirstLinestring = line;
if (p->LastLinestring != NULL)
p->LastLinestring->Next = line;
p->LastLinestring = line;
return line;
}
GAIAGEO_DECLARE void
gaiaInsertLinestringInGeomColl (gaiaGeomCollPtr p, gaiaLinestringPtr line)
{
/* adding an existing LINESTRING to this GEOMETRYCOLLECTION */
if (p->FirstLinestring == NULL)
p->FirstLinestring = line;
if (p->LastLinestring != NULL)
p->LastLinestring->Next = line;
p->LastLinestring = line;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaAddPolygonToGeomColl (gaiaGeomCollPtr p, int vert, int interiors)
{
/* adding a POLYGON to this GEOMETRYCOLLECTION */
gaiaPolygonPtr polyg;
if (p->DimensionModel == GAIA_XY_Z)
polyg = gaiaAllocPolygonXYZ (vert, interiors);
else if (p->DimensionModel == GAIA_XY_M)
polyg = gaiaAllocPolygonXYM (vert, interiors);
else if (p->DimensionModel == GAIA_XY_Z_M)
polyg = gaiaAllocPolygonXYZM (vert, interiors);
else
polyg = gaiaAllocPolygon (vert, interiors);
if (p->FirstPolygon == NULL)
p->FirstPolygon = polyg;
if (p->LastPolygon != NULL)
p->LastPolygon->Next = polyg;
p->LastPolygon = polyg;
return polyg;
}
GAIAGEO_DECLARE gaiaPolygonPtr
gaiaInsertPolygonInGeomColl (gaiaGeomCollPtr p, gaiaRingPtr ring)
{
/* adding a POLYGON to this GEOMETRYCOLLECTION */
gaiaPolygonPtr polyg;
polyg = malloc (sizeof (gaiaPolygon));
polyg->Exterior = ring;
polyg->NumInteriors = 0;
polyg->NextInterior = 0;
polyg->DimensionModel = ring->DimensionModel;
polyg->Next = NULL;
polyg->Interiors = NULL;
polyg->MinX = DBL_MAX;
polyg->MinY = DBL_MAX;
polyg->MaxX = -DBL_MAX;
polyg->MaxY = -DBL_MAX;
if (p->FirstPolygon == NULL)
p->FirstPolygon = polyg;
if (p->LastPolygon != NULL)
p->LastPolygon->Next = polyg;
p->LastPolygon = polyg;
return polyg;
}
GAIAGEO_DECLARE gaiaRingPtr
gaiaAddInteriorRing (gaiaPolygonPtr p, int pos, int vert)
{
/* adding an interior ring to some polygon */
gaiaRingPtr pP = p->Interiors + pos;
pP->Points = vert;
pP->DimensionModel = p->DimensionModel;
if (pP->DimensionModel == GAIA_XY_Z)
pP->Coords = malloc (sizeof (double) * (vert * 3));
else if (pP->DimensionModel == GAIA_XY_M)
pP->Coords = malloc (sizeof (double) * (vert * 3));
else if (pP->DimensionModel == GAIA_XY_Z_M)
pP->Coords = malloc (sizeof (double) * (vert * 4));
else
pP->Coords = malloc (sizeof (double) * (vert * 2));
return pP;
}
GAIAGEO_DECLARE void
gaiaInsertInteriorRing (gaiaPolygonPtr p, gaiaRingPtr ring)
{
/* adding an interior ring to some polygon */
gaiaRingPtr hole;
if (p->NumInteriors == 0)
{
/* this one is the first interior ring */
p->NumInteriors++;
p->Interiors = malloc (sizeof (gaiaRing));
hole = p->Interiors;
}
else
{
/* some interior ring is already defined */
gaiaRingPtr save = p->Interiors;
p->Interiors = malloc (sizeof (gaiaRing) * (p->NumInteriors + 1));
memcpy (p->Interiors, save, (sizeof (gaiaRing) * p->NumInteriors));
free (save);
hole = p->Interiors + p->NumInteriors;
p->NumInteriors++;
}
hole->Points = ring->Points;
hole->DimensionModel = p->DimensionModel;
if (hole->DimensionModel == GAIA_XY_Z)
hole->Coords = malloc (sizeof (double) * (hole->Points * 3));
else if (hole->DimensionModel == GAIA_XY_M)
hole->Coords = malloc (sizeof (double) * (hole->Points * 3));
else if (hole->DimensionModel == GAIA_XY_Z_M)
hole->Coords = malloc (sizeof (double) * (hole->Points * 4));
else
hole->Coords = malloc (sizeof (double) * (hole->Points * 2));
gaiaCopyRingCoords (hole, ring);
}
GAIAGEO_DECLARE void
gaiaAddRingToPolyg (gaiaPolygonPtr polyg, gaiaRingPtr ring)
{
/* adds an interior ring to this POLYGON */
gaiaRingPtr old_interiors = NULL;
if (!(polyg->Interiors))
{
/* this one is the first interior ring */
polyg->Interiors = ring;
polyg->NumInteriors = 1;
}
else
{
/* adding another interior ring */
old_interiors = polyg->Interiors;
polyg->Interiors =
malloc (sizeof (gaiaRing) * (polyg->NumInteriors + 1));
memcpy (polyg->Interiors, old_interiors,
(sizeof (gaiaRing) * polyg->NumInteriors));
memcpy (polyg->Interiors + polyg->NumInteriors, ring,
sizeof (gaiaRing));
(polyg->NumInteriors)++;
free (old_interiors);
free (ring);
}
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaAllocDynamicLine ()
{
/* DYNAMIC LINE object constructor */
gaiaDynamicLinePtr p = malloc (sizeof (gaiaDynamicLine));
p->Error = 0;
p->Srid = 0;
p->First = NULL;
p->Last = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreeDynamicLine (gaiaDynamicLinePtr p)
{
/* DYNAMIC LINE object destructor */
gaiaPointPtr pP;
gaiaPointPtr pPn;
pP = p->First;
while (pP != NULL)
{
pPn = pP->Next;
gaiaFreePoint (pP);
pP = pPn;
}
free (p);
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointToDynamicLine (gaiaDynamicLinePtr p, double x, double y)
{
/* inserts a new POINT to this DYNAMIC LINE after the last one */
gaiaPointPtr point = gaiaAllocPoint (x, y);
point->Prev = p->Last;
if (p->First == NULL)
p->First = point;
if (p->Last != NULL)
p->Last->Next = point;
p->Last = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointZToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double z)
{
/* inserts a new POINT to this DYNAMIC LINE after the last one */
gaiaPointPtr point = gaiaAllocPointXYZ (x, y, z);
point->Prev = p->Last;
if (p->First == NULL)
p->First = point;
if (p->Last != NULL)
p->Last->Next = point;
p->Last = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointMToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double m)
{
/* inserts a new POINT to this DYNAMIC LINE after the last one */
gaiaPointPtr point = gaiaAllocPointXYM (x, y, m);
point->Prev = p->Last;
if (p->First == NULL)
p->First = point;
if (p->Last != NULL)
p->Last->Next = point;
p->Last = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaAppendPointZMToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double z, double m)
{
/* inserts a new POINT to this DYNAMIC LINE after the last one */
gaiaPointPtr point = gaiaAllocPointXYZM (x, y, z, m);
point->Prev = p->Last;
if (p->First == NULL)
p->First = point;
if (p->Last != NULL)
p->Last->Next = point;
p->Last = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointToDynamicLine (gaiaDynamicLinePtr p, double x, double y)
{
/* inserts a new POINT to this DYNAMIC LINE before the first one */
gaiaPointPtr point = gaiaAllocPoint (x, y);
point->Next = p->First;
if (p->Last == NULL)
p->Last = point;
if (p->First != NULL)
p->First->Prev = point;
p->First = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointZToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double z)
{
/* inserts a new POINT to this DYNAMIC LINE before the first one */
gaiaPointPtr point = gaiaAllocPointXYZ (x, y, z);
point->Next = p->First;
if (p->Last == NULL)
p->Last = point;
if (p->First != NULL)
p->First->Prev = point;
p->First = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointMToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double m)
{
/* inserts a new POINT to this DYNAMIC LINE before the first one */
gaiaPointPtr point = gaiaAllocPointXYM (x, y, m);
point->Next = p->First;
if (p->Last == NULL)
p->Last = point;
if (p->First != NULL)
p->First->Prev = point;
p->First = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaPrependPointZMToDynamicLine (gaiaDynamicLinePtr p, double x, double y,
double z, double m)
{
/* inserts a new POINT to this DYNAMIC LINE before the first one */
gaiaPointPtr point = gaiaAllocPointXYZM (x, y, z, m);
point->Next = p->First;
if (p->Last == NULL)
p->Last = point;
if (p->First != NULL)
p->First->Prev = point;
p->First = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineInsertAfter (gaiaDynamicLinePtr p, gaiaPointPtr pt, double x,
double y)
{
/* inserts a new POINT to this DYNAMIC LINE after the referenced POINT */
gaiaPointPtr point = gaiaAllocPoint (x, y);
point->Prev = pt;
point->Next = pt->Next;
if (pt->Next)
pt->Next->Prev = point;
pt->Next = point;
if (pt == p->Last)
p->Last = point;
return point;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineInsertBefore (gaiaDynamicLinePtr p, gaiaPointPtr pt, double x,
double y)
{
/* inserts a new POINT to this DYNAMIC LINE before the referenced POINT */
gaiaPointPtr point = gaiaAllocPoint (x, y);
point->Next = pt;
point->Prev = pt->Prev;
if (pt->Prev)
pt->Prev->Next = point;
pt->Prev = point;
if (pt == p->First)
p->First = point;
return point;
}
GAIAGEO_DECLARE void
gaiaDynamicLineDeletePoint (gaiaDynamicLinePtr p, gaiaPointPtr pt)
{
/* deletes a POINT from this DYNAMIC LINE */
if (pt->Prev)
pt->Prev->Next = pt->Next;
if (pt->Next)
pt->Next->Prev = pt->Prev;
if (pt == p->First)
p->First = pt->Next;
if (pt == p->Last)
p->Last = pt->Prev;
gaiaFreePoint (pt);
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaCloneDynamicLine (gaiaDynamicLinePtr org)
{
/* creates a new line obtained by simply copying the current one */
gaiaPointPtr pt;
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
pt = org->First;
while (pt)
{
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
return dst;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaReverseDynamicLine (gaiaDynamicLinePtr org)
{
/* creates a new line obtained by inverting the current one */
gaiaPointPtr pt;
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
pt = org->Last;
while (pt)
{
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Prev;
}
return dst;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineSplitBefore (gaiaDynamicLinePtr org, gaiaPointPtr point)
{
/* creates a new line obtained by cutting the current one in two */
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
dst->First = org->First;
dst->Last = point->Prev;
point->Prev->Next = NULL;
org->First = point;
point->Prev = NULL;
return dst;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineSplitAfter (gaiaDynamicLinePtr org, gaiaPointPtr point)
{
/* creates a new line obtained by cutting the current one in two */
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
dst->First = point->Next;
dst->Last = org->Last;
point->Next->Prev = NULL;
org->Last = point;
point->Next = NULL;
return dst;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineJoinAfter (gaiaDynamicLinePtr org, gaiaPointPtr point,
gaiaDynamicLinePtr toJoin)
{
/* creates a new line obtained by joining the current one with another one */
gaiaPointPtr pt;
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
pt = org->First;
while (pt)
{
/* inserting the first slice since the delimiting POINT included */
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
if (pt == point)
break;
pt = pt->Next;
}
pt = toJoin->First;
while (pt)
{
/* inserting the other line */
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
pt = point->Next;
while (pt)
{
/* inserting the second slice after the delimiting POINT */
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
return dst;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaDynamicLineJoinBefore (gaiaDynamicLinePtr org, gaiaPointPtr point,
gaiaDynamicLinePtr toJoin)
{
/* creates a new line obtained by joining the current one with another one */
gaiaPointPtr pt;
gaiaDynamicLinePtr dst = gaiaAllocDynamicLine ();
pt = org->First;
while (pt)
{
/* inserting the first slice since the delimiting POINT excluded */
if (pt == point)
break;
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
pt = toJoin->First;
while (pt)
{
/* inserting the other line */
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
pt = point;
while (pt)
{
/* inserting the second slice beginning from the delimiting POINT */
gaiaAppendPointToDynamicLine (dst, pt->X, pt->Y);
pt = pt->Next;
}
return dst;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineFindByCoords (gaiaDynamicLinePtr p, double x, double y)
{
/* finds a POINT inside this DYNAMIC LINE */
gaiaPointPtr pP;
pP = p->First;
while (pP != NULL)
{
if (pP->X == x && pP->Y == y)
return pP;
pP = pP->Next;
}
return NULL;
}
GAIAGEO_DECLARE gaiaPointPtr
gaiaDynamicLineFindByPos (gaiaDynamicLinePtr p, int pos)
{
/* finds a POINT inside this DYNAMIC LINE */
int n = 0;
gaiaPointPtr pP;
pP = p->First;
while (pP != NULL)
{
if (pos == n)
return pP;
n++;
pP = pP->Next;
}
return NULL;
}
GAIAGEO_DECLARE gaiaDynamicLinePtr
gaiaCreateDynamicLine (double *coords, int points)
{
/* creates a DynamicLine from an array of coordinates */
int iv;
double x;
double y;
gaiaDynamicLinePtr line = gaiaAllocDynamicLine ();
for (iv = 0; iv < points; iv++)
{
gaiaGetPoint (coords, iv, &x, &y);
gaiaAppendPointToDynamicLine (line, x, y);
}
return line;
}
GAIAGEO_DECLARE void
gaiaMbrLinestring (gaiaLinestringPtr line)
{
/* computes the MBR for this linestring */
int iv;
double x;
double y;
double z;
double m;
line->MinX = DBL_MAX;
line->MinY = DBL_MAX;
line->MaxX = -DBL_MAX;
line->MaxY = -DBL_MAX;
for (iv = 0; iv < line->Points; iv++)
{
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);
}
if (x < line->MinX)
line->MinX = x;
if (y < line->MinY)
line->MinY = y;
if (x > line->MaxX)
line->MaxX = x;
if (y > line->MaxY)
line->MaxY = y;
}
}
GAIAGEO_DECLARE void
gaiaMbrRing (gaiaRingPtr rng)
{
/* computes the MBR for this ring */
int iv;
double x;
double y;
double z;
double m;
rng->MinX = DBL_MAX;
rng->MinY = DBL_MAX;
rng->MaxX = -DBL_MAX;
rng->MaxY = -DBL_MAX;
for (iv = 0; iv < rng->Points; iv++)
{
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (x < rng->MinX)
rng->MinX = x;
if (y < rng->MinY)
rng->MinY = y;
if (x > rng->MaxX)
rng->MaxX = x;
if (y > rng->MaxY)
rng->MaxY = y;
}
}
GAIAGEO_DECLARE void
gaiaMbrPolygon (gaiaPolygonPtr polyg)
{
/* computes the MBR for this polygon */
gaiaRingPtr rng;
polyg->MinX = DBL_MAX;
polyg->MinY = DBL_MAX;
polyg->MaxX = -DBL_MAX;
polyg->MaxY = -DBL_MAX;
rng = polyg->Exterior;
gaiaMbrRing (rng);
if (rng->MinX < polyg->MinX)
polyg->MinX = rng->MinX;
if (rng->MinY < polyg->MinY)
polyg->MinY = rng->MinY;
if (rng->MaxX > polyg->MaxX)
polyg->MaxX = rng->MaxX;
if (rng->MaxY > polyg->MaxY)
polyg->MaxY = rng->MaxY;
}
GAIAGEO_DECLARE void
gaiaMbrGeometry (gaiaGeomCollPtr geom)
{
/* computes the MBR for this geometry */
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
geom->MinX = DBL_MAX;
geom->MinY = DBL_MAX;
geom->MaxX = -DBL_MAX;
geom->MaxY = -DBL_MAX;
point = geom->FirstPoint;
while (point)
{
if (point->X < geom->MinX)
geom->MinX = point->X;
if (point->Y < geom->MinY)
geom->MinY = point->Y;
if (point->X > geom->MaxX)
geom->MaxX = point->X;
if (point->Y > geom->MaxY)
geom->MaxY = point->Y;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaMbrLinestring (line);
if (line->MinX < geom->MinX)
geom->MinX = line->MinX;
if (line->MinY < geom->MinY)
geom->MinY = line->MinY;
if (line->MaxX > geom->MaxX)
geom->MaxX = line->MaxX;
if (line->MaxY > geom->MaxY)
geom->MaxY = line->MaxY;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaMbrPolygon (polyg);
if (polyg->MinX < geom->MinX)
geom->MinX = polyg->MinX;
if (polyg->MinY < geom->MinY)
geom->MinY = polyg->MinY;
if (polyg->MaxX > geom->MaxX)
geom->MaxX = polyg->MaxX;
if (polyg->MaxY > geom->MaxY)
geom->MaxY = polyg->MaxY;
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE void
gaiaMRangeLinestring (gaiaLinestringPtr line, double *min, double *max)
{
/* computes the M-range [min/max] for this linestring */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < line->Points; iv++)
{
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);
}
if (m < *min)
*min = m;
if (m > *max)
*max = m;
}
}
GAIAGEO_DECLARE void
gaiaMRangeLinestringEx (gaiaLinestringPtr line, double nodata, double *min,
double *max)
{
/* computes the M-range [min/max] for this linestring (NODATA flavor) */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < line->Points; iv++)
{
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);
}
if (m == nodata)
continue;
if (m < *min)
*min = m;
if (m > *max)
*max = m;
}
}
GAIAGEO_DECLARE void
gaiaMRangeRing (gaiaRingPtr rng, double *min, double *max)
{
/* computes the M-range [min/max] for this ring */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < rng->Points; iv++)
{
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (m < *min)
*min = m;
if (m > *max)
*max = m;
}
}
GAIAGEO_DECLARE void
gaiaMRangeRingEx (gaiaRingPtr rng, double nodata, double *min, double *max)
{
/* computes the M-range [min/max] for this ring (NODATA flavor) */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < rng->Points; iv++)
{
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (m == nodata)
continue;
if (m < *min)
*min = m;
if (m > *max)
*max = m;
}
}
GAIAGEO_DECLARE void
gaiaMRangePolygon (gaiaPolygonPtr polyg, double *min, double *max)
{
/* computes the M-range [min/max] for this polygon */
gaiaRingPtr rng;
int ib;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
rng = polyg->Exterior;
gaiaMRangeRing (rng, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaMRangeRing (rng, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
}
}
GAIAGEO_DECLARE void
gaiaMRangePolygonEx (gaiaPolygonPtr polyg, double nodata, double *min,
double *max)
{
/* computes the M-range [min/max] for this polygon (NODATA flavor) */
gaiaRingPtr rng;
int ib;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
rng = polyg->Exterior;
gaiaMRangeRingEx (rng, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaMRangeRingEx (rng, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
}
}
GAIAGEO_DECLARE void
gaiaMRangeGeometry (gaiaGeomCollPtr geom, double *min, double *max)
{
/* computes the M-range [min/max] for this geometry */
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
double m;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
point = geom->FirstPoint;
while (point)
{
m = 0.0;
if (point->DimensionModel == GAIA_XY_M
|| point->DimensionModel == GAIA_XY_Z_M)
m = point->M;
if (m < *min)
*min = m;
if (m > *max)
*max = m;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaMRangeLinestring (line, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaMRangePolygon (polyg, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE void
gaiaMRangeGeometryEx (gaiaGeomCollPtr geom, double nodata, double *min,
double *max)
{
/* computes the M-range [min/max] for this geometry */
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
double m;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
point = geom->FirstPoint;
while (point)
{
m = 0.0;
if (point->DimensionModel == GAIA_XY_M
|| point->DimensionModel == GAIA_XY_Z_M)
m = point->M;
if (m == nodata)
continue;
if (m < *min)
*min = m;
if (m > *max)
*max = m;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaMRangeLinestringEx (line, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaMRangePolygonEx (polyg, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE void
gaiaZRangeLinestring (gaiaLinestringPtr line, double *min, double *max)
{
/* computes the Z-range [min/max] for this linestring */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < line->Points; iv++)
{
z = 0.0;
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);
}
if (z < *min)
*min = z;
if (z > *max)
*max = z;
}
}
GAIAGEO_DECLARE void
gaiaZRangeLinestringEx (gaiaLinestringPtr line, double nodata, double *min,
double *max)
{
/* computes the Z-range [min/max] for this linestring (NODATA flavor) */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < line->Points; iv++)
{
z = 0.0;
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);
}
if (z == nodata)
continue;
if (z < *min)
*min = z;
if (z > *max)
*max = z;
}
}
GAIAGEO_DECLARE void
gaiaZRangeRing (gaiaRingPtr rng, double *min, double *max)
{
/* computes the Z-range [min/max] for this ring */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (z < *min)
*min = z;
if (z > *max)
*max = z;
}
}
GAIAGEO_DECLARE void
gaiaZRangeRingEx (gaiaRingPtr rng, double nodata, double *min, double *max)
{
/* computes the Z-range [min/max] for this ring (NODATA flavor) */
int iv;
double x;
double y;
double z;
double m;
*min = DBL_MAX;
*max = -DBL_MAX;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (z == nodata)
continue;
if (z < *min)
*min = z;
if (z > *max)
*max = z;
}
}
GAIAGEO_DECLARE void
gaiaZRangePolygon (gaiaPolygonPtr polyg, double *min, double *max)
{
/* computes the Z-range [min/max] for this polygon */
gaiaRingPtr rng;
int ib;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
rng = polyg->Exterior;
gaiaZRangeRing (rng, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaZRangeRing (rng, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
}
}
GAIAGEO_DECLARE void
gaiaZRangePolygonEx (gaiaPolygonPtr polyg, double nodata, double *min,
double *max)
{
/* computes the Z-range [min/max] for this polygon (NODATA flavor) */
gaiaRingPtr rng;
int ib;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
rng = polyg->Exterior;
gaiaZRangeRingEx (rng, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaZRangeRingEx (rng, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
}
}
GAIAGEO_DECLARE void
gaiaZRangeGeometry (gaiaGeomCollPtr geom, double *min, double *max)
{
/* computes the Z-range [min/max] for this geometry */
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
double z;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
point = geom->FirstPoint;
while (point)
{
z = 0.0;
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
z = point->Z;
if (z < *min)
*min = z;
if (z > *max)
*max = z;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaZRangeLinestring (line, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaZRangePolygon (polyg, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE void
gaiaZRangeGeometryEx (gaiaGeomCollPtr geom, double nodata, double *min,
double *max)
{
/* computes the Z-range [min/max] for this geometry (NODATA flavor) */
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
double z;
double r_min;
double r_max;
*min = DBL_MAX;
*max = -DBL_MAX;
point = geom->FirstPoint;
while (point)
{
z = 0.0;
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
z = point->Z;
if (z == nodata)
continue;
if (z < *min)
*min = z;
if (z > *max)
*max = z;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaZRangeLinestringEx (line, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaZRangePolygonEx (polyg, nodata, &r_min, &r_max);
if (r_min < *min)
*min = r_min;
if (r_max > *max)
*max = r_max;
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE int
gaiaDimension (gaiaGeomCollPtr geom)
{
/* determines the Dimension for this geometry */
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
if (!geom)
return -1;
point = geom->FirstPoint;
while (point)
{
/* counts how many points are there */
n_points++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counts how many linestrings are there */
n_linestrings++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counts how many polygons are there */
n_polygons++;
polyg = polyg->Next;
}
if (n_points == 0 && n_linestrings == 0 && n_polygons == 0)
return -1;
if (n_points > 0 && n_linestrings == 0 && n_polygons == 0)
return 0;
if (n_linestrings > 0 && n_polygons == 0)
return 1;
return 2;
}
GAIAGEO_DECLARE int
gaiaGeometryType (gaiaGeomCollPtr geom)
{
/* determines the Class for this geometry */
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
int ib;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int dm = GAIA_XY;
if (!geom)
return GAIA_UNKNOWN;
point = geom->FirstPoint;
while (point)
{
/* counts how many points are there */
n_points++;
if (point->DimensionModel == GAIA_XY_Z)
{
if (dm == GAIA_XY)
dm = GAIA_XY_Z;
else if (dm == GAIA_XY_M)
dm = GAIA_XY_Z_M;
}
else if (point->DimensionModel == GAIA_XY_M)
{
if (dm == GAIA_XY)
dm = GAIA_XY_M;
else if (dm == GAIA_XY_Z)
dm = GAIA_XY_Z_M;
}
else if (point->DimensionModel == GAIA_XY_Z_M)
dm = GAIA_XY_Z_M;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counts how many linestrings are there */
n_linestrings++;
if (line->DimensionModel == GAIA_XY_Z)
{
if (dm == GAIA_XY)
dm = GAIA_XY_Z;
else if (dm == GAIA_XY_M)
dm = GAIA_XY_Z_M;
}
else if (line->DimensionModel == GAIA_XY_M)
{
if (dm == GAIA_XY)
dm = GAIA_XY_M;
else if (dm == GAIA_XY_Z)
dm = GAIA_XY_Z_M;
}
else if (line->DimensionModel == GAIA_XY_Z_M)
dm = GAIA_XY_Z_M;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counts how many polygons are there */
n_polygons++;
ring = polyg->Exterior;
if (ring->DimensionModel == GAIA_XY_Z)
{
if (dm == GAIA_XY)
dm = GAIA_XY_Z;
else if (dm == GAIA_XY_M)
dm = GAIA_XY_Z_M;
}
else if (ring->DimensionModel == GAIA_XY_M)
{
if (dm == GAIA_XY)
dm = GAIA_XY_M;
else if (dm == GAIA_XY_Z)
dm = GAIA_XY_Z_M;
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
dm = GAIA_XY_Z_M;
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
if (ring->DimensionModel == GAIA_XY_Z)
{
if (dm == GAIA_XY)
dm = GAIA_XY_Z;
else if (dm == GAIA_XY_M)
dm = GAIA_XY_Z_M;
}
else if (ring->DimensionModel == GAIA_XY_M)
{
if (dm == GAIA_XY)
dm = GAIA_XY_M;
else if (dm == GAIA_XY_Z)
dm = GAIA_XY_Z_M;
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
dm = GAIA_XY_Z_M;
}
polyg = polyg->Next;
}
if (n_points == 0 && n_linestrings == 0 && n_polygons == 0)
return GAIA_UNKNOWN;
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
{
if (dm == GAIA_XY_Z)
return GAIA_MULTIPOINTZ;
if (dm == GAIA_XY_M)
return GAIA_MULTIPOINTM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTIPOINTZM;
else
return GAIA_MULTIPOINT;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_POINTZ;
if (dm == GAIA_XY_M)
return GAIA_POINTM;
if (dm == GAIA_XY_Z_M)
return GAIA_POINTZM;
else
return GAIA_POINT;
}
}
if (n_points > 0 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_MULTIPOINTZ;
if (dm == GAIA_XY_M)
return GAIA_MULTIPOINTM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTIPOINTZM;
else
return GAIA_MULTIPOINT;
}
}
if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
{
if (dm == GAIA_XY_Z)
return GAIA_MULTILINESTRINGZ;
if (dm == GAIA_XY_M)
return GAIA_MULTILINESTRINGM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTILINESTRINGZM;
else
return GAIA_MULTILINESTRING;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_LINESTRINGZ;
if (dm == GAIA_XY_M)
return GAIA_LINESTRINGM;
if (dm == GAIA_XY_Z_M)
return GAIA_LINESTRINGZM;
else
return GAIA_LINESTRING;
}
}
if (n_points == 0 && n_linestrings > 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_MULTILINESTRINGZ;
if (dm == GAIA_XY_M)
return GAIA_MULTILINESTRINGM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTILINESTRINGZM;
else
return GAIA_MULTILINESTRING;
}
}
if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
{
if (dm == GAIA_XY_Z)
return GAIA_MULTIPOLYGONZ;
if (dm == GAIA_XY_M)
return GAIA_MULTIPOLYGONM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTIPOLYGONZM;
else
return GAIA_MULTIPOLYGON;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_POLYGONZ;
if (dm == GAIA_XY_M)
return GAIA_POLYGONM;
if (dm == GAIA_XY_Z_M)
return GAIA_POLYGONZM;
else
return GAIA_POLYGON;
}
}
if (n_points == 0 && n_linestrings == 0 && n_polygons > 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
else
{
if (dm == GAIA_XY_Z)
return GAIA_MULTIPOLYGONZ;
if (dm == GAIA_XY_M)
return GAIA_MULTIPOLYGONM;
if (dm == GAIA_XY_Z_M)
return GAIA_MULTIPOLYGONZM;
else
return GAIA_MULTIPOLYGON;
}
}
if (dm == GAIA_XY_Z)
return GAIA_GEOMETRYCOLLECTIONZ;
if (dm == GAIA_XY_M)
return GAIA_GEOMETRYCOLLECTIONM;
if (dm == GAIA_XY_Z_M)
return GAIA_GEOMETRYCOLLECTIONZM;
else
return GAIA_GEOMETRYCOLLECTION;
}
GAIAGEO_DECLARE int
gaiaGeometryAliasType (gaiaGeomCollPtr geom)
{
/* determines the AliasClass for this geometry */
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
if (!geom)
return GAIA_UNKNOWN;
point = geom->FirstPoint;
while (point)
{
/* counts how many points are there */
n_points++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counts how many linestrings are there */
n_linestrings++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counts how many polygons are there */
n_polygons++;
polyg = polyg->Next;
}
if (n_points == 0 && n_linestrings == 0 && n_polygons == 0)
return GAIA_UNKNOWN;
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
return GAIA_MULTIPOINT;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_POINT;
}
if (n_points >= 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_MULTIPOINT;
}
if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
return GAIA_MULTILINESTRING;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_LINESTRING;
}
if (n_points == 0 && n_linestrings >= 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_MULTILINESTRING;
}
if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
return GAIA_MULTIPOLYGON;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_POLYGON;
}
if (n_points == 0 && n_linestrings == 0 && n_polygons >= 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return GAIA_GEOMETRYCOLLECTION;
else
return GAIA_MULTIPOLYGON;
}
return GAIA_GEOMETRYCOLLECTION;
}
GAIAGEO_DECLARE int
gaiaIsEmpty (gaiaGeomCollPtr geom)
{
/* checks if this GEOMETRYCOLLECTION is an empty one */
if (!geom)
return 1;
if (geom->FirstPoint != NULL)
{
/* there is at least one point */
return 0;
}
if (geom->FirstLinestring != NULL)
{
/* there is at least one linestring */
return 0;
}
if (geom->FirstPolygon != NULL)
{
/* there is at least one polygon */
return 0;
}
return 1;
}
GAIAGEO_DECLARE int
gaiaIsClosed (gaiaLinestringPtr line)
{
/* checks if this linestring is a closed one */
double x0;
double y0;
double x1;
double y1;
double z;
double m;
if (!line)
return 0;
if (line->Points < 3)
return 0;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (line->Coords, 0, &x0, &y0, &z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (line->Coords, 0, &x0, &y0, &m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (line->Coords, 0, &x0, &y0, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, 0, &x0, &y0);
}
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (line->Coords, (line->Points - 1), &x1, &y1, &z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (line->Coords, (line->Points - 1), &x1, &y1, &m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (line->Coords, (line->Points - 1), &x1, &y1, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, (line->Points - 1), &x1, &y1);
}
if (x0 == x1 && y0 == y1)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaMbrsEqual (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if two MBRs are identical
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
if (mbr1->MinX != mbr2->MinX)
return 0;
if (mbr1->MinY != mbr2->MinY)
return 0;
if (mbr1->MaxX != mbr2->MaxX)
return 0;
if (mbr1->MaxY != mbr2->MaxY)
return 0;
return 1;
}
GAIAGEO_DECLARE int
gaiaMbrsDisjoint (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if two MBRs are disjoint
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
if (mbr1->MinX > mbr2->MaxX)
return 1;
if (mbr1->MinY > mbr2->MaxY)
return 1;
if (mbr1->MaxX < mbr2->MinX)
return 1;
if (mbr1->MaxY < mbr2->MinY)
return 1;
if (mbr2->MinX > mbr1->MaxX)
return 1;
if (mbr2->MinY > mbr1->MaxY)
return 1;
if (mbr2->MaxX < mbr1->MinX)
return 1;
if (mbr2->MaxY < mbr1->MinY)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaMbrsTouches (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if two MBRs touches
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
if (mbr1->MinX == mbr2->MinX)
return 1;
if (mbr1->MinY == mbr2->MinY)
return 1;
if (mbr1->MaxX == mbr2->MaxX)
return 1;
if (mbr1->MaxY == mbr2->MaxY)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaMbrsIntersects (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if two MBRs intersect
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
if (gaiaMbrsDisjoint (mbr1, mbr2))
return 0;
return 1;
}
GAIAGEO_DECLARE int
gaiaMbrsOverlaps (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if two MBRs overlap
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
if (gaiaMbrsDisjoint (mbr1, mbr2))
return 0;
if (mbr1->MinX >= mbr2->MinX && mbr1->MinX <= mbr2->MaxX)
return 1;
if (mbr1->MaxX >= mbr2->MinX && mbr1->MaxX <= mbr2->MaxX)
return 1;
if (mbr1->MinY >= mbr2->MinY && mbr1->MinY <= mbr2->MaxY)
return 1;
if (mbr1->MaxY >= mbr2->MinY && mbr1->MaxY <= mbr2->MaxY)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaMbrsContains (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if MBR-1 completely contains MBR-2
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
int ok_1 = 0;
int ok_2 = 0;
int ok_3 = 0;
int ok_4 = 0;
if (mbr2->MinX >= mbr1->MinX && mbr2->MinX <= mbr1->MaxX)
ok_1 = 1;
if (mbr2->MaxX >= mbr1->MinX && mbr2->MaxX <= mbr1->MaxX)
ok_2 = 1;
if (mbr2->MinY >= mbr1->MinY && mbr2->MinY <= mbr1->MaxY)
ok_3 = 1;
if (mbr2->MaxY >= mbr1->MinY && mbr2->MaxY <= mbr1->MaxY)
ok_4 = 1;
if (ok_1 && ok_2 && ok_3 && ok_4)
return 1;
return 0;
}
GAIAGEO_DECLARE int
gaiaMbrsWithin (gaiaGeomCollPtr mbr1, gaiaGeomCollPtr mbr2)
{
/*
/ checks if MBR-2 completely contains MBR-1
/
/ returns 1 if TRUE
/ 0 if FALSE
*/
int ok_1 = 0;
int ok_2 = 0;
int ok_3 = 0;
int ok_4 = 0;
if (mbr1->MinX >= mbr2->MinX && mbr1->MinX <= mbr2->MaxX)
ok_1 = 1;
if (mbr1->MaxX >= mbr2->MinX && mbr1->MaxX <= mbr2->MaxX)
ok_2 = 1;
if (mbr1->MinY >= mbr2->MinY && mbr1->MinY <= mbr2->MaxY)
ok_3 = 1;
if (mbr1->MaxY >= mbr2->MinY && mbr1->MaxY <= mbr2->MaxY)
ok_4 = 1;
if (ok_1 && ok_2 && ok_3 && ok_4)
return 1;
return 0;
}
static void
fatMakePoint (double x, double y, int srid, unsigned char **result, int *size)
{
/* build a Blob encoded Geometry representing a POINT */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* computing the Blob size and then allocating it */
*size = 44; /* header size */
*size += (sizeof (double) * 2); /* [x,y] coords */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, y, 1, endian_arch); /* Y */
*(ptr + 59) = GAIA_MARK_END; /* END signature */
}
static void
tinyMakePoint (double x, double y, int srid, unsigned char **result, int *size)
{
/* build a Blob encoded TinyPoint representing a POINT */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* allocating the BLOB */
*size = 24;
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_TINYPOINT_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
*(ptr + 6) = GAIA_TINYPOINT_XY; /* Point Type */
gaiaExport64 (ptr + 7, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 15, y, 1, endian_arch); /* Y */
*(ptr + 23) = GAIA_MARK_END; /* END signature */
}
GAIAGEO_DECLARE void
gaiaMakePoint (double x, double y, int srid, unsigned char **result, int *size)
{
/* always returns a BLOB-Geometry encoded POINT */
gaiaMakePointEx (0, x, y, srid, result, size);
}
GAIAGEO_DECLARE void
gaiaMakePointEx (int tiny_point, double x, double y, int srid,
unsigned char **result, int *size)
{
/* conditionally returns either a BLOB-Geometry or BLOB-TinyPoint encoded POINT */
if (tiny_point)
tinyMakePoint (x, y, srid, result, size);
else
fatMakePoint (x, y, srid, result, size);
}
static void
fatMakePointZ (double x, double y, double z, int srid, unsigned char **result,
int *size)
{
/* build a Blob encoded Geometry representing a POINT Z */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* computing the Blob size and then allocating it */
*size = 44; /* header size */
*size += (sizeof (double) * 3); /* [x,y,z] coords */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZ, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, z, 1, endian_arch); /* Z */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
}
static void
tinyMakePointZ (double x, double y, double z, int srid, unsigned char **result,
int *size)
{
/* build a Blob encoded TinyPoint representing a POINT Z */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* allocating the BLOB */
*size = 32;
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_TINYPOINT_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
*(ptr + 6) = GAIA_TINYPOINT_XYZ; /* Point Type */
gaiaExport64 (ptr + 7, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 15, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 23, z, 1, endian_arch); /* Z */
*(ptr + 31) = GAIA_MARK_END; /* END signature */
}
GAIAGEO_DECLARE void
gaiaMakePointZ (double x, double y, double z, int srid, unsigned char **result,
int *size)
{
/* always returns a BLOB-Geometry encoded POINT Z */
gaiaMakePointZEx (0, x, y, z, srid, result, size);
}
GAIAGEO_DECLARE void
gaiaMakePointZEx (int tiny_point, double x, double y, double z, int srid,
unsigned char **result, int *size)
{
/* conditionally returns either a BLOB-Geometry or BLOB-TinyPoint encoded POINT Z */
if (tiny_point)
tinyMakePointZ (x, y, z, srid, result, size);
else
fatMakePointZ (x, y, z, srid, result, size);
}
static void
fatMakePointM (double x, double y, double m, int srid, unsigned char **result,
int *size)
{
/* build a Blob encoded Geometry representing a POINT M */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* computing the Blob size and then allocating it */
*size = 44; /* header size */
*size += (sizeof (double) * 3); /* [x,y,z] coords */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTM, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, m, 1, endian_arch); /* M */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
}
static void
tinyMakePointM (double x, double y, double m, int srid, unsigned char **result,
int *size)
{
/* build a Blob encoded TinyPoint representing a POINT M */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* allocating the BLOB */
*size = 32;
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_TINYPOINT_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
*(ptr + 6) = GAIA_TINYPOINT_XYM; /* Point Type */
gaiaExport64 (ptr + 7, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 15, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 23, m, 1, endian_arch); /* M */
*(ptr + 31) = GAIA_MARK_END; /* END signature */
}
GAIAGEO_DECLARE void
gaiaMakePointM (double x, double y, double m, int srid, unsigned char **result,
int *size)
{
/* always returns a BLOB-Geometry encoded POINT M */
gaiaMakePointMEx (0, x, y, m, srid, result, size);
}
GAIAGEO_DECLARE void
gaiaMakePointMEx (int tiny_point, double x, double y, double m, int srid,
unsigned char **result, int *size)
{
/* conditionally returns either a BLOB-Geometry or BLOB-TinyPoint encoded POINT M */
if (tiny_point)
tinyMakePointM (x, y, m, srid, result, size);
else
fatMakePointM (x, y, m, srid, result, size);
}
static void
fatMakePointZM (double x, double y, double z, double m, int srid,
unsigned char **result, int *size)
{
/* build a Blob encoded Geometry representing a POINT ZM */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* computing the Blob size and then allocating it */
*size = 44; /* header size */
*size += (sizeof (double) * 4); /* [x,y,z,m] coords */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZM, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 67, m, 1, endian_arch); /* M */
*(ptr + 75) = GAIA_MARK_END; /* END signature */
}
static void
tinyMakePointZM (double x, double y, double z, double m, int srid,
unsigned char **result, int *size)
{
/* build a Blob encoded TinyPoint representing a POINT ZM */
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
/* allocating the BLOB */
*size = 40;
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_TINYPOINT_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
*(ptr + 6) = GAIA_TINYPOINT_XYZM; /* Point Type */
gaiaExport64 (ptr + 7, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 15, y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 23, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 31, m, 1, endian_arch); /* M */
*(ptr + 39) = GAIA_MARK_END; /* END signature */
}
GAIAGEO_DECLARE void
gaiaMakePointZM (double x, double y, double z, double m, int srid,
unsigned char **result, int *size)
{
/* always returns a BLOB-Geometry encoded POINT ZM */
gaiaMakePointZMEx (0, x, y, z, m, srid, result, size);
}
GAIAGEO_DECLARE void
gaiaMakePointZMEx (int tiny_point, double x, double y, double z, double m,
int srid, unsigned char **result, int *size)
{
/* conditionally returns either a BLOB-Geometry or BLOB-TinyPoint encoded POINT ZM */
if (tiny_point)
tinyMakePointZM (x, y, z, m, srid, result, size);
else
fatMakePointZM (x, y, z, m, srid, result, size);
}
GAIAGEO_DECLARE void
gaiaMakeLine (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
unsigned char **result, int *size)
{
/* build a Blob encoded Geometry representing a LINESTRING (segment) */
int pts;
int lns;
int pgs;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaGeomCollPtr g;
int dims0 = 0;
int dims1 = 0;
int dims;
double x0 = 0.0;
double y0 = 0.0;
double z0 = 0.0;
double m0 = 0.0;
double x1 = 0.0;
double y1 = 0.0;
double z1 = 0.0;
double m1 = 0.0;
/* checking if GEOM-1 simply is a POINT */
if (geom1 == NULL)
{
*result = NULL;
*size = 0;
return;
}
pts = 0;
lns = 0;
pgs = 0;
pt = geom1->FirstPoint;
while (pt)
{
pts++;
x0 = pt->X;
y0 = pt->Y;
z0 = pt->Z;
m0 = pt->M;
dims0 = pt->DimensionModel;
pt = pt->Next;
}
ln = geom1->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom1->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 1 && lns == 0 && pgs == 0)
;
else
{
/* failure: not a simple POINT */
*result = NULL;
*size = 0;
return;
}
/* checking if GEOM-2 simply is a POINT */
if (geom2 == NULL)
{
*result = NULL;
*size = 0;
return;
}
pts = 0;
lns = 0;
pgs = 0;
pt = geom2->FirstPoint;
while (pt)
{
pts++;
x1 = pt->X;
y1 = pt->Y;
z1 = pt->Z;
m1 = pt->M;
dims1 = pt->DimensionModel;
pt = pt->Next;
}
ln = geom2->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom2->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 1 && lns == 0 && pgs == 0)
;
else
{
/* failure: not a simple POINT */
*result = NULL;
*size = 0;
return;
}
/* building a new Geometry */
if (dims0 == dims1)
dims = dims0;
else
{
if (dims0 == GAIA_XY_Z_M || dims1 == GAIA_XY_Z_M)
dims = GAIA_XY_Z_M;
else if (dims0 == GAIA_XY_Z && dims1 == GAIA_XY_M)
dims = GAIA_XY_Z_M;
else if (dims0 == GAIA_XY_M && dims1 == GAIA_XY_Z)
dims = GAIA_XY_Z_M;
else if (dims0 == GAIA_XY_Z)
dims = GAIA_XY_Z;
else if (dims1 == GAIA_XY_Z)
dims = GAIA_XY_Z;
else if (dims0 == GAIA_XY_M)
dims = GAIA_XY_M;
else if (dims1 == GAIA_XY_M)
dims = GAIA_XY_M;
else
dims = GAIA_XY;
}
if (dims == GAIA_XY_Z_M)
g = gaiaAllocGeomCollXYZM ();
else if (dims == GAIA_XY_Z)
g = gaiaAllocGeomCollXYZ ();
else if (dims == GAIA_XY_M)
g = gaiaAllocGeomCollXYM ();
else
g = gaiaAllocGeomColl ();
g->Srid = geom1->Srid;
g->DeclaredType = GAIA_LINESTRING;
ln = gaiaAddLinestringToGeomColl (g, 2);
if (dims == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, 0, x0, y0, z0, m0);
gaiaSetPointXYZM (ln->Coords, 1, x1, y1, z1, m1);
}
else if (dims == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, 0, x0, y0, z0);
gaiaSetPointXYZ (ln->Coords, 1, x1, y1, z1);
}
else if (dims == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, 0, x0, y0, m0);
gaiaSetPointXYM (ln->Coords, 1, x1, y1, m1);
}
else
{
gaiaSetPoint (ln->Coords, 0, x0, y0);
gaiaSetPoint (ln->Coords, 1, x1, y1);
}
/* converting to Binary Blob */
gaiaToSpatiaLiteBlobWkb (g, result, size);
gaiaFreeGeomColl (g);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMergeGeometries (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
return gaiaMergeGeometries_r (NULL, geom1, geom2);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMergeGeometries_r (const void *cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* mergine a second generic Geometries into the first one */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr new_ln;
gaiaPolygonPtr pg;
gaiaPolygonPtr new_pg;
gaiaRingPtr rng;
gaiaRingPtr new_rng;
double x;
double y;
double z;
double m;
int iv;
int ib;
if (geom1 == NULL || geom2 == NULL)
return NULL;
if (cache != NULL)
cache = NULL;
pt = geom2->FirstPoint;
while (pt)
{
/* copying POINTs from GEOM-2 */
z = 0.0;
m = 0.0;
if (pt->DimensionModel == GAIA_XY_Z_M)
{
x = pt->X;
y = pt->Y;
z = pt->Z;
m = pt->M;
}
else if (pt->DimensionModel == GAIA_XY_Z)
{
x = pt->X;
y = pt->Y;
z = pt->Z;
}
else if (pt->DimensionModel == GAIA_XY_M)
{
x = pt->X;
y = pt->Y;
m = pt->M;
}
else
{
x = pt->X;
y = pt->Y;
}
if (geom1->DimensionModel == GAIA_XY_Z_M)
{
gaiaAddPointToGeomCollXYZM (geom1, x, y, z, m);
}
else if (geom1->DimensionModel == GAIA_XY_Z)
{
gaiaAddPointToGeomCollXYZ (geom1, x, y, z);
}
else if (geom1->DimensionModel == GAIA_XY_M)
{
gaiaAddPointToGeomCollXYM (geom1, x, y, m);
}
else
{
gaiaAddPointToGeomColl (geom1, x, y);
}
pt = pt->Next;
}
ln = geom2->FirstLinestring;
while (ln)
{
/* copying LINESTRINGs from GEOM-2 */
new_ln = gaiaAddLinestringToGeomColl (geom1, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
m = 0.0;
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (new_ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else if (new_ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (new_ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else
{
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
ln = ln->Next;
}
pg = geom2->FirstPolygon;
while (pg)
{
/* copying POLYGONs from GEOM-2 */
rng = pg->Exterior;
new_pg =
gaiaAddPolygonToGeomColl (geom1, rng->Points, pg->NumInteriors);
new_rng = new_pg->Exterior;
for (iv = 0; iv < rng->Points; iv++)
{
/* Exterior Ring */
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (new_rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m);
}
else if (new_rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z);
}
else if (new_rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_rng->Coords, iv, x, y, m);
}
else
{
gaiaSetPoint (new_rng->Coords, iv, x, y);
}
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* Interior Rings */
rng = pg->Interiors + ib;
new_rng = gaiaAddInteriorRing (new_pg, ib, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (new_rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m);
}
else if (new_rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z);
}
else if (new_rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_rng->Coords, iv, x, y, m);
}
else
{
gaiaSetPoint (new_rng->Coords, iv, x, y);
}
}
}
pg = pg->Next;
}
return geom1;
}
GAIAGEO_DECLARE void
gaiaBuildMbr (double x1, double y1, double x2, double y2, int srid,
unsigned char **result, int *size)
{
/* build a Blob encoded Geometry representing an MBR */
unsigned char *ptr;
double minx;
double maxx;
double miny;
double maxy;
int endian_arch = gaiaEndianArch ();
/* computing MinMax coords */
if (x1 > x2)
{
maxx = x1;
minx = x2;
}
else
{
minx = x1;
maxx = x2;
}
if (y1 > y2)
{
maxy = y1;
miny = y2;
}
else
{
miny = y1;
maxy = y2;
}
/* computing the Blob size and then allocating it */
*size = 44; /* header size */
*size += (8 + ((sizeof (double) * 2) * 5)); /* # rings + # points + [x.y] array - exterior ring */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, minx, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, miny, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, maxx, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, maxy, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POLYGON, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 43, 1, 1, endian_arch); /* # rings */
gaiaExport32 (ptr + 47, 5, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
/* setting Envelope points */
gaiaExport64 (ptr, minx, 1, endian_arch);
gaiaExport64 (ptr + 8, miny, 1, endian_arch);
ptr += 16;
gaiaExport64 (ptr, maxx, 1, endian_arch);
gaiaExport64 (ptr + 8, miny, 1, endian_arch);
ptr += 16;
gaiaExport64 (ptr, maxx, 1, endian_arch);
gaiaExport64 (ptr + 8, maxy, 1, endian_arch);
ptr += 16;
gaiaExport64 (ptr, minx, 1, endian_arch);
gaiaExport64 (ptr + 8, maxy, 1, endian_arch);
ptr += 16;
gaiaExport64 (ptr, minx, 1, endian_arch);
gaiaExport64 (ptr + 8, miny, 1, endian_arch);
ptr += 16;
*ptr = GAIA_MARK_END; /* END signature */
}
GAIAGEO_DECLARE void
gaiaBuildCircleMbr (double x, double y, double radius, int srid,
unsigned char **result, int *size)
{
/* build a Blob encoded Geometry representing an MBR */
int sz;
unsigned char *res = NULL;
double minx = x - radius;
double maxx = x + radius;
double miny = y - radius;
double maxy = y + radius;
gaiaBuildMbr (minx, miny, maxx, maxy, srid, &res, &sz);
if (!res)
{
*result = NULL;
*size = 0;
}
else
{
*result = res;
*size = sz;
}
}
GAIAGEO_DECLARE void
gaiaBuildFilterMbr (double x1, double y1, double x2, double y2, int mode,
unsigned char **result, int *size)
{
/* build a filter for an MBR */
unsigned char *ptr;
double minx;
double maxx;
double miny;
double maxy;
int endian_arch = gaiaEndianArch ();
char filter = GAIA_FILTER_MBR_WITHIN;
if (mode == GAIA_FILTER_MBR_CONTAINS)
filter = GAIA_FILTER_MBR_CONTAINS;
if (mode == GAIA_FILTER_MBR_INTERSECTS)
filter = GAIA_FILTER_MBR_INTERSECTS;
if (mode == GAIA_FILTER_MBR_DECLARE)
filter = GAIA_FILTER_MBR_DECLARE;
/* computing MinMax coords */
if (x1 > x2)
{
maxx = x1;
minx = x2;
}
else
{
minx = x1;
maxx = x2;
}
if (y1 > y2)
{
maxy = y1;
miny = y2;
}
else
{
miny = y1;
maxy = y2;
}
/* computing the Blob size and then allocating it */
*size = 37; /* MBR filter size */
*result = malloc (*size);
ptr = *result;
/* setting the Blob value */
*ptr = filter; /* signature */
ptr++;
gaiaExport64 (ptr, minx, 1, endian_arch); /* MBR - minimum X */
ptr += 8;
*ptr = filter; /* signature */
ptr++;
gaiaExport64 (ptr, miny, 1, endian_arch); /* MBR - minimum Y */
ptr += 8;
*ptr = filter; /* signature */
ptr++;
gaiaExport64 (ptr, maxx, 1, endian_arch); /* MBR - maximum X */
ptr += 8;
*ptr = filter; /* signature */
ptr++;
gaiaExport64 (ptr, maxy, 1, endian_arch); /* MBR - maximum Y */
ptr += 8;
*ptr = filter; /* signature */
}
GAIAGEO_DECLARE int
gaiaParseFilterMbr (unsigned char *ptr, int size, double *minx, double *miny,
double *maxx, double *maxy, int *mode)
{
/* parsing a filter for an MBR */
char decl_mode;
int endian_arch = gaiaEndianArch ();
if (size != 37)
return 0; /* cannot be an MBR Filter */
if (!ptr)
return 0; /* cannot be an MBR Filter */
decl_mode = *(ptr + 0);
if (decl_mode == GAIA_FILTER_MBR_WITHIN)
;
else if (decl_mode == GAIA_FILTER_MBR_CONTAINS)
;
else if (decl_mode == GAIA_FILTER_MBR_INTERSECTS)
;
else if (decl_mode == GAIA_FILTER_MBR_DECLARE)
;
else
return 0; /* cannot be an MBR Filter */
if (*(ptr + 9)
== decl_mode
&& *(ptr +
18) ==
decl_mode && *(ptr + 27) == decl_mode && *(ptr + 36) == decl_mode)
;
else
return 0; /* cannot be an MBR Filter */
*mode = decl_mode;
*minx = gaiaImport64 (ptr + 1, 1, endian_arch);
*miny = gaiaImport64 (ptr + 10, 1, endian_arch);
*maxx = gaiaImport64 (ptr + 19, 1, endian_arch);
*maxy = gaiaImport64 (ptr + 28, 1, endian_arch);
return 1;
}
GAIAGEO_DECLARE int
gaiaGetMbrMinX (const unsigned char *blob, unsigned int size, double *minx)
{
/* returns the MinX coordinate value for a Blob encoded Geometry */
int little_endian;
int endian_arch = gaiaEndianArch ();
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
{
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*minx = gaiaImport64 (blob + 7, little_endian, endian_arch);
return 1;
}
}
if (size < 45)
return 0; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return 0; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return 0; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return 0; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*minx = gaiaImport64 (blob + 6, little_endian, endian_arch);
return 1;
}
GAIAGEO_DECLARE int
gaiaGetMbrMaxX (const unsigned char *blob, unsigned int size, double *maxx)
{
/* returns the MaxX coordinate value for a Blob encoded Geometry */
int little_endian;
int endian_arch = gaiaEndianArch ();
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
{
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*maxx = gaiaImport64 (blob + 7, little_endian, endian_arch);
return 1;
}
}
if (size < 45)
return 0; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return 0; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return 0; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return 0; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*maxx = gaiaImport64 (blob + 22, little_endian, endian_arch);
return 1;
}
GAIAGEO_DECLARE int
gaiaGetMbrMinY (const unsigned char *blob, unsigned int size, double *miny)
{
/* returns the MinY coordinate value for a Blob encoded Geometry */
int little_endian;
int endian_arch = gaiaEndianArch ();
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
{
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*miny = gaiaImport64 (blob + 15, little_endian, endian_arch);
return 1;
}
}
if (size < 45)
return 0; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return 0; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return 0; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return 0; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*miny = gaiaImport64 (blob + 14, little_endian, endian_arch);
return 1;
}
GAIAGEO_DECLARE int
gaiaGetMbrMaxY (const unsigned char *blob, unsigned int size, double *maxy)
{
/* returns the MaxY coordinate value for a Blob encoded Geometry */
int little_endian;
int endian_arch = gaiaEndianArch ();
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
{
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*maxy = gaiaImport64 (blob + 15, little_endian, endian_arch);
return 1;
}
}
if (size < 45)
return 0; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return 0; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return 0; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return 0; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return 0; /* unknown encoding; neither little-endian nor big-endian */
*maxy = gaiaImport64 (blob + 30, little_endian, endian_arch);
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaAddMeasure (gaiaGeomCollPtr geom, double m_start, double m_end)
{
/* linearly interpolates M-values between the start and end points. */
double total_length;
double progressive_length;
gaiaGeomCollPtr geo2;
gaiaLinestringPtr pL;
gaiaLinestringPtr pL2;
int iv;
double x;
double y;
double z;
double m;
double x0;
double y0;
double mm;
double percent;
double interval = m_end - m_start;
if (!geom)
return NULL;
/* only Linestring or MultiLinestrings are accepted */
if (geom->FirstPoint != NULL)
return NULL;
if (geom->FirstPolygon != NULL)
return NULL;
if (geom->FirstLinestring == NULL)
return NULL;
/* computing the total length */
total_length = 0.0;
pL = geom->FirstLinestring;
while (pL != NULL)
{
for (iv = 0; iv < pL->Points; iv++)
{
z = 0.0;
m = 0.0;
if (pL->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (pL->Coords, iv, &x, &y, &z);
}
else if (pL->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (pL->Coords, iv, &x, &y, &m);
}
else if (pL->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (pL->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (pL->Coords, iv, &x, &y);
}
if (iv != 0)
total_length +=
sqrt (((x0 - x) * (x0 - x)) + ((y0 - y) * (y0 - y)));
x0 = x;
y0 = y;
}
pL = pL->Next;
}
/* creating the output geometry */
progressive_length = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
geo2 = gaiaAllocGeomCollXYZM ();
else if (geom->DimensionModel == GAIA_XY_M)
geo2 = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo2 = gaiaAllocGeomCollXYZM ();
else
geo2 = gaiaAllocGeomCollXYM ();
geo2->Srid = geom->Srid;
pL = geom->FirstLinestring;
while (pL != NULL)
{
pL2 = gaiaAddLinestringToGeomColl (geo2, pL->Points);
for (iv = 0; iv < pL->Points; iv++)
{
z = 0.0;
m = 0.0;
if (pL->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (pL->Coords, iv, &x, &y, &z);
}
else if (pL->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (pL->Coords, iv, &x, &y, &m);
}
else if (pL->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (pL->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (pL->Coords, iv, &x, &y);
}
if (iv != 0)
progressive_length +=
sqrt (((x0 - x) * (x0 - x)) + ((y0 - y) * (y0 - y)));
x0 = x;
y0 = y;
/* linealy interpolating M-values */
percent = progressive_length / total_length;
mm = m_start + (interval * percent);
if (pL2->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (pL2->Coords, iv, x, y, mm);
}
else
{
gaiaSetPointXYZM (pL2->Coords, iv, x, y, z, mm);
}
}
pL = pL->Next;
}
return geo2;
}
GAIAGEO_DECLARE int
gaiaInterpolatePoint (const void *p_cache, gaiaGeomCollPtr line,
gaiaGeomCollPtr point, double *m_value)
{
/* Will interpolate the M-value for a LinestringM at the point closest to the given Point */
gaiaLinestringPtr pL;
int iv;
double x;
double y;
double m;
double z;
double fraction;
double x0;
double y0;
double m0;
double progressive_length;
double pl0;
double length;
double normalized_len;
if (!line)
return 0;
if (!point)
return 0;
/* only a Linestring M is accepted as the first geom */
if (line->FirstPoint != NULL)
return 0;
if (line->FirstPolygon != NULL)
return 0;
if (line->FirstLinestring == NULL)
return 0;
if (line->FirstLinestring != line->LastLinestring)
return 0;
if (line->DimensionModel == GAIA_XY_M
|| line->DimensionModel == GAIA_XY_Z_M)
;
else
return 0;
/* only a Point is accepted as the second geom */
if (point->FirstPolygon != NULL)
return 0;
if (point->FirstLinestring != NULL)
return 0;
if (point->FirstPoint == NULL)
return 0;
if (point->FirstPoint != point->LastPoint)
return 0;
#ifndef OMIT_GEOS /* only if GEOS is supported */
/* locating the Point along the Line */
if (p_cache != NULL)
{
if (!gaiaGeomCollLengthOrPerimeter_r (p_cache, line, 0, &length))
return 0;
fraction = gaiaLineLocatePoint_r (p_cache, line, point);
}
else
{
if (!gaiaGeomCollLengthOrPerimeter (line, 0, &length))
return 0;
fraction = gaiaLineLocatePoint (line, point);
}
normalized_len = length * fraction;
pL = line->FirstLinestring;
if (fraction <= 0.0)
{
/* special case: assuming the start point */
z = 0.0;
if (pL->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (pL->Coords, 0, &x, &y, &m);
}
else
{
gaiaGetPointXYZM (pL->Coords, 0, &x, &y, &z, &m);
}
*m_value = m;
return 1;
}
if (fraction >= 1.0)
{
/* special case: assuming the end point */
z = 0.0;
iv = pL->Points - 1;
if (pL->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (pL->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPointXYZM (pL->Coords, iv, &x, &y, &z, &m);
}
*m_value = m;
return 1;
}
/* computing the progressive length */
progressive_length = 0.0;
for (iv = 0; iv < pL->Points; iv++)
{
z = 0.0;
if (pL->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (pL->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPointXYZM (pL->Coords, iv, &x, &y, &z, &m);
}
if (iv != 0)
{
double length =
sqrt (((x0 - x) * (x0 - x)) + ((y0 - y) * (y0 - y)));
progressive_length += length;
if (progressive_length == normalized_len)
{
/* special case: exactly intercepting a vertex */
*m_value = m;
return 1;
}
if (progressive_length > normalized_len)
{
/* interpolating the M-Value */
double interval = m - m0;
double diff = normalized_len - pl0;
double ratio = diff / length;
*m_value = m0 + (interval * ratio);
break;
}
}
x0 = x;
y0 = y;
m0 = m;
pl0 = progressive_length;
}
return 1;
#else
return 0;
#endif /* end GEOS conditional */
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLocateBetweenMeasures (gaiaGeomCollPtr geom, double m_start, double m_end)
{
/* extracts points/linestrings accordingly to a range of measures */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr new_geom = NULL;
gaiaDynamicLinePtr dyn = NULL;
int iv;
double x;
double y;
double z;
double m;
if (!geom)
return NULL;
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
return NULL;
if (geom->FirstPolygon != NULL)
return NULL;
if (geom->DimensionModel == GAIA_XY_M)
new_geom = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
new_geom = gaiaAllocGeomCollXYZM ();
else
return NULL;
new_geom->Srid = geom->Srid;
new_geom->DeclaredType = geom->DeclaredType;
pt = geom->FirstPoint;
while (pt)
{
/* extracting POINTs */
if (pt->M >= m_start && pt->M <= m_end)
{
if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom, pt->X, pt->Y, pt->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom, pt->X, pt->Y,
pt->Z, pt->M);
}
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* extracting LINESTRINGs */
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
if (m >= m_start && m <= m_end)
{
/* found a valid vertex */
if (dyn == NULL)
dyn = gaiaAllocDynamicLine ();
if (ln->DimensionModel == GAIA_XY_Z_M)
gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m);
else
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
}
else
{
if (dyn != NULL)
{
/* evaluting the latest sequence found */
int cnt = 0;
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
cnt++;
pt = pt->Next;
}
if (cnt > 1)
{
/* creating a Linestring */
new_line =
gaiaAddLinestringToGeomColl (new_geom,
cnt);
cnt = 0;
pt = dyn->First;
while (pt)
{
if (new_line->DimensionModel ==
GAIA_XY_Z_M)
{
gaiaSetPointXYZM
(new_line->Coords, cnt, pt->X,
pt->Y, pt->Z, pt->M);
}
else
{
gaiaSetPointXYM (new_line->Coords,
cnt, pt->X,
pt->Y, pt->M);
}
cnt++;
pt = pt->Next;
}
}
else if (cnt == 1)
{
/* creating a Point */
pt = dyn->First;
if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom,
pt->X, pt->Y,
pt->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom,
pt->X, pt->Y,
pt->Z, pt->M);
}
gaiaFreeDynamicLine (dyn);
dyn = NULL;
}
}
}
if (dyn != NULL)
{
/* evaluting the latest sequence found */
int cnt = 0;
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
cnt++;
pt = pt->Next;
}
if (cnt > 1)
{
/* creating a Linestring */
new_line = gaiaAddLinestringToGeomColl (new_geom, cnt);
cnt = 0;
pt = dyn->First;
while (pt)
{
if (new_line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_line->Coords, cnt,
pt->X, pt->Y, pt->Z, pt->M);
}
else
{
gaiaSetPointXYM (new_line->Coords,
cnt, pt->X, pt->Y, pt->M);
}
cnt++;
pt = pt->Next;
}
}
else if (cnt == 1)
{
/* creating a Point */
pt = dyn->First;
if (geom->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (new_geom,
pt->X, pt->Y, pt->M);
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (new_geom,
pt->X, pt->Y,
pt->Z, pt->M);
}
gaiaFreeDynamicLine (dyn);
dyn = NULL;
}
ln = ln->Next;
}
if (new_geom->FirstPoint == NULL && new_geom->FirstLinestring == NULL)
{
/* empty result: returning NULL */
gaiaFreeGeomColl (new_geom);
return NULL;
}
return new_geom;
}
GAIAGEO_DECLARE int
gaiaIsValidTrajectory (gaiaGeomCollPtr geom)
{
/* Checks if a Geometry object is valid Trajectory */
gaiaLinestringPtr ln;
int iv;
double x;
double y;
double z;
double m;
double prev_m;
if (!geom)
return 0;
if (geom->FirstPoint != NULL || geom->FirstLinestring == NULL
|| geom->FirstPolygon != NULL)
return 0; /* not a Linestring */
if (geom->FirstLinestring != geom->LastLinestring)
return 0; /* not a simple Linestring */
if (geom->DimensionModel == GAIA_XY_M
|| geom->DimensionModel == GAIA_XY_Z_M)
;
else
return 0; /* not supporting M_values */
ln = geom->FirstLinestring;
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
if (iv != 0)
{
if (m <= prev_m)
return 0;
}
prev_m = m;
}
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTrajectoryInterpolatePoint (gaiaGeomCollPtr geom, double m_value)
{
/* attempts to interpolate a Point along a Trajectory accordingly to given M-Value */
gaiaGeomCollPtr point;
gaiaLinestringPtr ln;
int iv;
double x;
double y;
double z;
double m;
double prev_x;
double prev_y;
double prev_z;
double prev_m;
if (!gaiaIsValidTrajectory (geom))
return NULL;
/* creating the Geometry to be returned */
if (geom->DimensionModel == GAIA_XY_M)
point = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
point = gaiaAllocGeomCollXYZM ();
else
return NULL;
point->Srid = geom->Srid;
point->DeclaredType = GAIA_POINT;
ln = geom->FirstLinestring;
/* testing if m < StartPoint */
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPointXYM (ln->Coords, 0, &x, &y, &m);
}
if (m_value < m)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (point, x, y, z, m_value);
else
gaiaAddPointToGeomCollXYM (point, x, y, m_value);
return point;
}
/* testing if m > EndPoint */
iv = ln->Points - 1;
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
if (m_value > m)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (point, x, y, z, m_value);
else
gaiaAddPointToGeomCollXYM (point, x, y, m_value);
return point;
}
prev_m = 0.0 - DBL_MAX;
ln = geom->FirstLinestring;
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
if (m_value == m)
{
if (ln->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (point, x, y, z, m_value);
else
gaiaAddPointToGeomCollXYM (point, x, y, m_value);
return point;
}
if (m_value > prev_m && m_value < m)
{
/* interpolating the Point */
double ix;
double iy;
double iz;
double diff = m - prev_m;
double m_diff = m_value - prev_m;
double ratio = diff / m_diff;
diff = x - prev_x;
ix = prev_x + (diff / ratio);
diff = y - prev_y;
iy = prev_y + (diff / ratio);
diff = z - prev_z;
iz = prev_z + (diff / ratio);
if (ln->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (point, ix, iy, iz, m_value);
else
gaiaAddPointToGeomCollXYM (point, ix, iy, m_value);
return point;
}
prev_x = x;
prev_y = y;
prev_z = z;
prev_m = m;
}
gaiaFreeGeomColl (point);
return NULL;
}
static int
check_closed_multi_linestring (gaiaGeomCollPtr geom, int single)
{
/* check if :
/ - this geometry is a (multi) Linestring
/ - all Linestrings are effectively closed
*/
int pts = 0;
int lns = 0;
int pgs = 0;
int closed = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
if (gaiaIsClosed (ln))
closed++;
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (closed != lns)
return 0;
if (single)
{
if (pts == 0 && lns == 1 && pgs == 0)
return lns;
}
else
{
if (pts == 0 && lns >= 1 && pgs == 0)
return lns;
}
return 0;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakePolygon (gaiaGeomCollPtr exterior, gaiaGeomCollPtr interiors)
{
/* reassembling a Polygon from closed Linestrings */
gaiaGeomCollPtr geom;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaLinestringPtr ln;
int iv;
double x;
double y;
double z;
double m;
int num_interiors = 0;
int ib;
if (exterior == NULL)
return NULL;
if (!check_closed_multi_linestring (exterior, 1))
return NULL;
if (interiors != NULL)
{
num_interiors = check_closed_multi_linestring (interiors, 0);
if (!num_interiors)
return NULL;
}
/* reassembling the Polygon */
if (exterior->DimensionModel == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (exterior->DimensionModel == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (exterior->DimensionModel == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
geom->Srid = exterior->Srid;
ln = exterior->FirstLinestring;
pg = gaiaAddPolygonToGeomColl (geom, ln->Points, num_interiors);
rng = pg->Exterior;
for (iv = 0; iv < ln->Points; iv++)
{
/* exterior ring */
m = 0.0;
z = 0.0;
switch (ln->DimensionModel)
{
case GAIA_XY:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
return 0;
};
switch (rng->DimensionModel)
{
case GAIA_XY:
gaiaSetPoint (rng->Coords, iv, x, y);
break;
case GAIA_XY_Z:
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
break;
};
}
if (interiors != NULL)
{
/* setting up the interior rings */
ib = 0;
ln = interiors->FirstLinestring;
while (ln)
{
rng = gaiaAddInteriorRing (pg, ib, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
m = 0.0;
z = 0.0;
switch (ln->DimensionModel)
{
case GAIA_XY:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
return 0;
};
switch (rng->DimensionModel)
{
case GAIA_XY:
gaiaSetPoint (rng->Coords, iv, x, y);
break;
case GAIA_XY_Z:
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
break;
};
}
ib++;
ln = ln->Next;
}
}
return geom;
}
libspatialite-5.1.0/src/gaiageo/gg_geoscvt.c 0000644 0001750 0001750 00000170736 14463127014 015762 0000000 0000000 /*
gg_geoscvt.c -- Gaia / GEOS conversion [Geometry]
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#ifndef OMIT_GEOS /* including GEOS */
#ifdef GEOS_REENTRANT
#ifdef GEOS_ONLY_REENTRANT
#define GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
#endif
#endif
#include
#endif
#include
#include
#include
#ifndef OMIT_GEOS /* including GEOS */
static GEOSGeometry *
toGeosGeometry (const void *cache, GEOSContextHandle_t handle,
const gaiaGeomCollPtr gaia, int mode)
{
/* converting a GAIA Geometry into a GEOS Geometry */
int pts = 0;
int lns = 0;
int pgs = 0;
int type;
int geos_type;
unsigned int dims;
int iv;
int ib;
int nItem;
double x;
double y;
double z;
double m;
double x0 = 0.0;
double y0 = 0.0;
double z0 = 0.0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
GEOSGeometry *geos = NULL;
GEOSGeometry *geos_ext;
GEOSGeometry *geos_int;
GEOSGeometry *geos_item;
GEOSGeometry **geos_holes;
GEOSGeometry **geos_coll;
GEOSCoordSequence *cs;
int ring_points;
int n_items;
#ifdef GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
if (handle == NULL)
return NULL;
#endif
if (!gaia)
return NULL;
pt = gaia->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = gaia->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
/* counting how many POLYGONs are there */
pgs++;
pg = pg->Next;
}
if (mode == GAIA2GEOS_ONLY_POINTS && pts == 0)
return NULL;
if (mode == GAIA2GEOS_ONLY_LINESTRINGS && lns == 0)
return NULL;
if (mode == GAIA2GEOS_ONLY_POLYGONS && pgs == 0)
return NULL;
if (pts == 0 && lns == 0 && pgs == 0)
return NULL;
else if (pts == 1 && lns == 0 && pgs == 0)
{
if (gaia->DeclaredType == GAIA_MULTIPOINT)
type = GAIA_MULTIPOINT;
else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POINT;
}
else if (pts == 0 && lns == 1 && pgs == 0)
{
if (gaia->DeclaredType == GAIA_MULTILINESTRING)
type = GAIA_MULTILINESTRING;
else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_LINESTRING;
}
else if (pts == 0 && lns == 0 && pgs == 1)
{
if (gaia->DeclaredType == GAIA_MULTIPOLYGON)
type = GAIA_MULTIPOLYGON;
else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POLYGON;
}
else if (pts > 1 && lns == 0 && pgs == 0)
{
if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOINT;
}
else if (pts == 0 && lns > 1 && pgs == 0)
{
if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTILINESTRING;
}
else if (pts == 0 && lns == 0 && pgs > 1)
{
if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOLYGON;
}
else
type = GAIA_GEOMETRYCOLLECTION;
switch (gaia->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
dims = 3;
break;
default:
dims = 2;
break;
};
switch (type)
{
case GAIA_POINT:
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POINTS)
{
pt = gaia->FirstPoint;
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 1, dims);
switch (gaia->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
GEOSCoordSeq_setZ_r (handle, cs, 0, pt->Z);
break;
default:
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
break;
};
geos = GEOSGeom_createPoint_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (1, dims);
switch (gaia->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
GEOSCoordSeq_setZ (cs, 0, pt->Z);
break;
default:
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
break;
};
geos = GEOSGeom_createPoint (cs);
#endif
}
}
break;
case GAIA_LINESTRING:
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_LINESTRINGS)
{
ln = gaia->FirstLinestring;
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ln->Points, dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ln->Points, dims);
#endif
for (iv = 0; iv < ln->Points; iv++)
{
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
};
}
if (handle != NULL)
geos = GEOSGeom_createLineString_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos = GEOSGeom_createLineString (cs);
#endif
}
break;
case GAIA_POLYGON:
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POLYGONS)
{
pg = gaia->FirstPolygon;
rng = pg->Exterior;
/* exterior ring */
ring_points = rng->Points;
if (cache)
{
if (gaiaIsNotClosedRing_r (cache, rng))
ring_points++;
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
if (gaiaIsNotClosedRing (rng))
ring_points++;
}
#endif
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ring_points, dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ring_points, dims);
#endif
for (iv = 0; iv < rng->Points; iv++)
{
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
};
}
if (ring_points > rng->Points)
{
/* ensuring Ring's closure */
iv = ring_points - 1;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x0);
GEOSCoordSeq_setY_r (handle, cs, iv, y0);
GEOSCoordSeq_setZ_r (handle, cs, iv, z0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
GEOSCoordSeq_setZ (cs, iv, z0);
#endif
}
break;
default:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x0);
GEOSCoordSeq_setY_r (handle, cs, iv, y0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
#endif
}
break;
};
}
if (handle != NULL)
geos_ext = GEOSGeom_createLinearRing_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_ext = GEOSGeom_createLinearRing (cs);
#endif
geos_holes = NULL;
if (pg->NumInteriors > 0)
{
geos_holes =
malloc (sizeof (GEOSGeometry *) * pg->NumInteriors);
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
ring_points = rng->Points;
if (cache != NULL)
{
if (gaiaIsNotClosedRing_r (cache, rng))
ring_points++;
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
if (gaiaIsNotClosedRing (rng))
ring_points++;
}
#endif
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ring_points,
dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ring_points, dims);
#endif
for (iv = 0; iv < rng->Points; iv++)
{
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x,
&y, &z);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x);
GEOSCoordSeq_setY_r (handle, cs,
iv, y);
GEOSCoordSeq_setZ_r (handle, cs,
iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x,
&y, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x);
GEOSCoordSeq_setY_r (handle, cs,
iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x,
&y, &z, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x);
GEOSCoordSeq_setY_r (handle, cs,
iv, y);
GEOSCoordSeq_setZ_r (handle, cs,
iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x);
GEOSCoordSeq_setY_r (handle, cs,
iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
};
}
if (ring_points > rng->Points)
{
/* ensuring Ring's closure */
iv = ring_points - 1;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x0);
GEOSCoordSeq_setY_r (handle, cs,
iv, y0);
GEOSCoordSeq_setZ_r (handle, cs,
iv, z0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
GEOSCoordSeq_setZ (cs, iv, z0);
#endif
}
break;
default:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs,
iv, x0);
GEOSCoordSeq_setY_r (handle, cs,
iv, y0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
#endif
}
break;
};
}
if (handle != NULL)
geos_int =
GEOSGeom_createLinearRing_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_int = GEOSGeom_createLinearRing (cs);
#endif
*(geos_holes + ib) = geos_int;
}
}
if (handle != NULL)
geos =
GEOSGeom_createPolygon_r (handle, geos_ext, geos_holes,
pg->NumInteriors);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos =
GEOSGeom_createPolygon (geos_ext, geos_holes,
pg->NumInteriors);
#endif
if (geos_holes)
free (geos_holes);
}
break;
case GAIA_MULTIPOINT:
case GAIA_MULTILINESTRING:
case GAIA_MULTIPOLYGON:
case GAIA_GEOMETRYCOLLECTION:
nItem = 0;
if (mode == GAIA2GEOS_ONLY_POINTS)
{
geos_coll = malloc (sizeof (GEOSGeometry *) * (pts));
n_items = pts;
}
else if (mode == GAIA2GEOS_ONLY_LINESTRINGS)
{
geos_coll = malloc (sizeof (GEOSGeometry *) * (lns));
n_items = lns;
}
else if (mode == GAIA2GEOS_ONLY_POLYGONS)
{
geos_coll = malloc (sizeof (GEOSGeometry *) * (pgs));
n_items = pgs;
}
else
{
geos_coll =
malloc (sizeof (GEOSGeometry *) * (pts + lns + pgs));
n_items = pts + lns + pgs;
}
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POINTS)
{
pt = gaia->FirstPoint;
while (pt)
{
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, 1, dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (1, dims);
#endif
switch (pt->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
GEOSCoordSeq_setZ_r (handle, cs, 0, pt->Z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
GEOSCoordSeq_setZ (cs, 0, pt->Z);
#endif
}
break;
default:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
#endif
}
break;
};
if (handle != NULL)
geos_item = GEOSGeom_createPoint_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_item = GEOSGeom_createPoint (cs);
#endif
*(geos_coll + nItem++) = geos_item;
pt = pt->Next;
}
}
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_LINESTRINGS)
{
ln = gaia->FirstLinestring;
while (ln)
{
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ln->Points, dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ln->Points, dims);
#endif
for (iv = 0; iv < ln->Points; iv++)
{
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z,
&m);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
};
}
if (handle != NULL)
geos_item = GEOSGeom_createLineString_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_item = GEOSGeom_createLineString (cs);
#endif
*(geos_coll + nItem++) = geos_item;
ln = ln->Next;
}
}
if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POLYGONS)
{
pg = gaia->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
/* exterior ring */
ring_points = rng->Points;
if (cache != NULL)
{
if (gaiaIsNotClosedRing_r (cache, rng))
ring_points++;
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
if (gaiaIsNotClosedRing (rng))
ring_points++;
}
#endif
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ring_points,
dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ring_points, dims);
#endif
for (iv = 0; iv < rng->Points; iv++)
{
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z,
&m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
break;
};
}
if (ring_points > rng->Points)
{
/* ensuring Ring's closure */
iv = ring_points - 1;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv,
x0);
GEOSCoordSeq_setY_r (handle, cs, iv,
y0);
GEOSCoordSeq_setZ_r (handle, cs, iv,
z0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
GEOSCoordSeq_setZ (cs, iv, z0);
#endif
}
break;
default:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv,
x0);
GEOSCoordSeq_setY_r (handle, cs, iv,
y0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x0);
GEOSCoordSeq_setY (cs, iv, y0);
#endif
}
break;
};
}
if (handle != NULL)
geos_ext = GEOSGeom_createLinearRing_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_ext = GEOSGeom_createLinearRing (cs);
#endif
geos_holes = NULL;
if (pg->NumInteriors > 0)
{
geos_holes =
malloc (sizeof (GEOSGeometry *) *
pg->NumInteriors);
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
ring_points = rng->Points;
if (cache != NULL)
{
if (gaiaIsNotClosedRing_r (cache, rng))
ring_points++;
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
if (gaiaIsNotClosedRing (rng))
ring_points++;
}
#endif
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle,
ring_points,
dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ring_points,
dims);
#endif
for (iv = 0; iv < rng->Points; iv++)
{
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv,
&x, &y, &z);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y);
GEOSCoordSeq_setZ_r (handle,
cs, iv,
z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x);
GEOSCoordSeq_setY (cs, iv,
y);
GEOSCoordSeq_setZ (cs, iv,
z);
#endif
}
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv,
&x, &y, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x);
GEOSCoordSeq_setY (cs, iv,
y);
#endif
}
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv,
&x, &y, &z, &m);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
z0 = z;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y);
GEOSCoordSeq_setZ_r (handle,
cs, iv,
z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x);
GEOSCoordSeq_setY (cs, iv,
y);
GEOSCoordSeq_setZ (cs, iv,
z);
#endif
}
break;
default:
gaiaGetPoint (rng->Coords, iv, &x,
&y);
if (iv == 0)
{
/* saving the first vertex */
x0 = x;
y0 = y;
}
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x);
GEOSCoordSeq_setY (cs, iv,
y);
#endif
}
break;
};
}
if (ring_points > rng->Points)
{
/* ensuring Ring's closure */
iv = ring_points - 1;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x0);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y0);
GEOSCoordSeq_setZ_r (handle,
cs, iv,
z0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x0);
GEOSCoordSeq_setY (cs, iv,
y0);
GEOSCoordSeq_setZ (cs, iv,
z0);
#endif
}
break;
default:
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle,
cs, iv,
x0);
GEOSCoordSeq_setY_r (handle,
cs, iv,
y0);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv,
x0);
GEOSCoordSeq_setY (cs, iv,
y0);
#endif
}
break;
};
}
if (handle != NULL)
geos_int =
GEOSGeom_createLinearRing_r (handle,
cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_int = GEOSGeom_createLinearRing (cs);
#endif
*(geos_holes + ib) = geos_int;
}
}
if (handle != NULL)
geos_item =
GEOSGeom_createPolygon_r (handle, geos_ext,
geos_holes,
pg->NumInteriors);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_item =
GEOSGeom_createPolygon (geos_ext, geos_holes,
pg->NumInteriors);
#endif
if (geos_holes)
free (geos_holes);
*(geos_coll + nItem++) = geos_item;
pg = pg->Next;
}
}
geos_type = GEOS_GEOMETRYCOLLECTION;
if (type == GAIA_MULTIPOINT)
geos_type = GEOS_MULTIPOINT;
if (type == GAIA_MULTILINESTRING)
geos_type = GEOS_MULTILINESTRING;
if (type == GAIA_MULTIPOLYGON)
geos_type = GEOS_MULTIPOLYGON;
if (handle != NULL)
geos =
GEOSGeom_createCollection_r (handle, geos_type, geos_coll,
n_items);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos = GEOSGeom_createCollection (geos_type, geos_coll, n_items);
#endif
if (geos_coll)
free (geos_coll);
break;
default:
geos = NULL;
};
if (geos)
{
if (handle != NULL)
GEOSSetSRID_r (handle, geos, gaia->Srid);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
GEOSSetSRID (geos, gaia->Srid);
#endif
}
return geos;
}
static int
check_empty_geom (gaiaGeomCollPtr geom)
{
/* checking for EMTPY Geometries */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
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 || lns || pgs)
return 0;
return 1;
}
static gaiaGeomCollPtr
fromGeosGeometry (GEOSContextHandle_t handle, const GEOSGeometry * geos,
const int dimension_model)
{
/* converting a GEOS Geometry into a GAIA Geometry */
int type;
int itemType;
unsigned int dims;
int iv;
int ib;
int it;
int sub_it;
int nItems;
int nSubItems;
int holes;
unsigned int points;
double x;
double y;
double z;
const GEOSCoordSequence *cs;
const GEOSGeometry *geos_ring;
const GEOSGeometry *geos_item;
const GEOSGeometry *geos_sub_item;
gaiaGeomCollPtr gaia = NULL;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
#ifdef GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
if (handle == NULL)
return NULL;
#endif
if (!geos)
return NULL;
if (handle != NULL)
type = GEOSGeomTypeId_r (handle, geos);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
type = GEOSGeomTypeId (geos);
#endif
if (type < 0)
return NULL;
switch (type)
{
case GEOS_POINT:
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
gaia->DeclaredType = GAIA_POINT;
if (handle != NULL)
{
gaia->Srid = GEOSGetSRID_r (handle, geos);
cs = GEOSGeom_getCoordSeq_r (handle, geos);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaia->Srid = GEOSGetSRID (geos);
cs = GEOSGeom_getCoordSeq (geos);
GEOSCoordSeq_getDimensions (cs, &dims);
#endif
}
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, 0, &x);
GEOSCoordSeq_getY_r (handle, cs, 0, &y);
GEOSCoordSeq_getZ_r (handle, cs, 0, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, 0, &x);
GEOSCoordSeq_getY (cs, 0, &y);
GEOSCoordSeq_getZ (cs, 0, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, 0, &x);
GEOSCoordSeq_getY_r (handle, cs, 0, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, 0, &x);
GEOSCoordSeq_getY (cs, 0, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
else if (dimension_model == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
else if (dimension_model == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
else
gaiaAddPointToGeomColl (gaia, x, y);
break;
case GEOS_LINESTRING:
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
gaia->DeclaredType = GAIA_LINESTRING;
if (handle != NULL)
{
gaia->Srid = GEOSGetSRID_r (handle, geos);
cs = GEOSGeom_getCoordSeq_r (handle, geos);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaia->Srid = GEOSGetSRID (geos);
cs = GEOSGeom_getCoordSeq (geos);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
if (points <= 0)
goto skip_empty_linestring;
ln = gaiaAddLinestringToGeomColl (gaia, points);
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
skip_empty_linestring:
break;
case GEOS_POLYGON:
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
gaia->DeclaredType = GAIA_POLYGON;
if (handle != NULL)
gaia->Srid = GEOSGetSRID_r (handle, geos);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
gaia->Srid = GEOSGetSRID (geos);
#endif
/* exterior ring */
if (handle != NULL)
{
holes = GEOSGetNumInteriorRings_r (handle, geos);
geos_ring = GEOSGetExteriorRing_r (handle, geos);
cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
holes = GEOSGetNumInteriorRings (geos);
geos_ring = GEOSGetExteriorRing (geos);
cs = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
if (points <= 0)
goto skip_empty_polygon;
pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
rng = pg->Exterior;
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
for (ib = 0; ib < holes; ib++)
{
/* interior rings */
if (handle != NULL)
{
geos_ring = GEOSGetInteriorRingN_r (handle, geos, ib);
cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_ring = GEOSGetInteriorRingN (geos, ib);
cs = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
rng = gaiaAddInteriorRing (pg, ib, points);
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
skip_empty_polygon:
break;
case GEOS_MULTIPOINT:
case GEOS_MULTILINESTRING:
case GEOS_MULTIPOLYGON:
case GEOS_GEOMETRYCOLLECTION:
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
if (type == GEOS_MULTIPOINT)
gaia->DeclaredType = GAIA_MULTIPOINT;
else if (type == GEOS_MULTILINESTRING)
gaia->DeclaredType = GAIA_MULTILINESTRING;
else if (type == GEOS_MULTIPOLYGON)
gaia->DeclaredType = GAIA_MULTIPOLYGON;
else
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
if (handle != NULL)
{
gaia->Srid = GEOSGetSRID_r (handle, geos);
nItems = GEOSGetNumGeometries_r (handle, geos);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaia->Srid = GEOSGetSRID (geos);
nItems = GEOSGetNumGeometries (geos);
#endif
}
for (it = 0; it < nItems; it++)
{
/* looping on elementaty geometries */
if (handle != NULL)
{
geos_item = GEOSGetGeometryN_r (handle, geos, it);
itemType = GEOSGeomTypeId_r (handle, geos_item);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_item = GEOSGetGeometryN (geos, it);
itemType = GEOSGeomTypeId (geos_item);
#endif
}
switch (itemType)
{
case GEOS_POINT:
if (handle != NULL)
{
cs = GEOSGeom_getCoordSeq_r (handle, geos_item);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSGeom_getCoordSeq (geos_item);
GEOSCoordSeq_getDimensions (cs, &dims);
#endif
}
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, 0, &x);
GEOSCoordSeq_getY_r (handle, cs, 0, &y);
GEOSCoordSeq_getZ_r (handle, cs, 0, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, 0, &x);
GEOSCoordSeq_getY (cs, 0, &y);
GEOSCoordSeq_getZ (cs, 0, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, 0, &x);
GEOSCoordSeq_getY_r (handle, cs, 0, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, 0, &x);
GEOSCoordSeq_getY (cs, 0, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
else if (dimension_model == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
else if (dimension_model == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
else
gaiaAddPointToGeomColl (gaia, x, y);
break;
case GEOS_LINESTRING:
if (handle != NULL)
{
cs = GEOSGeom_getCoordSeq_r (handle, geos_item);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSGeom_getCoordSeq (geos_item);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
ln = gaiaAddLinestringToGeomColl (gaia, points);
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv,
&x);
GEOSCoordSeq_getY_r (handle, cs, iv,
&y);
GEOSCoordSeq_getZ_r (handle, cs, iv,
&z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv,
&x);
GEOSCoordSeq_getY_r (handle, cs, iv,
&y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y, z,
0.0);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
break;
case GEOS_MULTILINESTRING:
if (handle != NULL)
nSubItems =
GEOSGetNumGeometries_r (handle, geos_item);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
nSubItems = GEOSGetNumGeometries (geos_item);
#endif
for (sub_it = 0; sub_it < nSubItems; sub_it++)
{
/* looping on elementaty geometries */
if (handle != NULL)
{
geos_sub_item =
GEOSGetGeometryN_r (handle, geos_item,
sub_it);
cs = GEOSGeom_getCoordSeq_r (handle,
geos_sub_item);
GEOSCoordSeq_getDimensions_r (handle, cs,
&dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_sub_item =
GEOSGetGeometryN (geos_item, sub_it);
cs = GEOSGeom_getCoordSeq (geos_sub_item);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
ln = gaiaAddLinestringToGeomColl (gaia, points);
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs,
iv, &x);
GEOSCoordSeq_getY_r (handle, cs,
iv, &y);
GEOSCoordSeq_getZ_r (handle, cs,
iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs,
iv, &x);
GEOSCoordSeq_getY_r (handle, cs,
iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y,
z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y,
0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y,
z, 0.0);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
}
break;
case GEOS_POLYGON:
/* exterior ring */
if (handle != NULL)
{
holes =
GEOSGetNumInteriorRings_r (handle, geos_item);
geos_ring =
GEOSGetExteriorRing_r (handle, geos_item);
cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
holes = GEOSGetNumInteriorRings (geos_item);
geos_ring = GEOSGetExteriorRing (geos_item);
cs = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
rng = pg->Exterior;
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv,
&x);
GEOSCoordSeq_getY_r (handle, cs, iv,
&y);
GEOSCoordSeq_getZ_r (handle, cs, iv,
&z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv,
&x);
GEOSCoordSeq_getY_r (handle, cs, iv,
&y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z,
0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
for (ib = 0; ib < holes; ib++)
{
/* interior rings */
if (handle != NULL)
{
geos_ring =
GEOSGetInteriorRingN_r (handle, geos_item,
ib);
cs = GEOSGeom_getCoordSeq_r (handle,
geos_ring);
GEOSCoordSeq_getDimensions_r (handle, cs,
&dims);
GEOSCoordSeq_getSize_r (handle, cs, &points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_ring =
GEOSGetInteriorRingN (geos_item, ib);
cs = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (cs, &dims);
GEOSCoordSeq_getSize (cs, &points);
#endif
}
rng = gaiaAddInteriorRing (pg, ib, points);
for (iv = 0; iv < (int) points; iv++)
{
if (dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs,
iv, &x);
GEOSCoordSeq_getY_r (handle, cs,
iv, &y);
GEOSCoordSeq_getZ_r (handle, cs,
iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
GEOSCoordSeq_getZ (cs, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs,
iv, &x);
GEOSCoordSeq_getY_r (handle, cs,
iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
z = 0.0;
}
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y,
z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y,
0.0);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y,
z, 0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
break;
};
}
break;
};
if (check_empty_geom (gaia))
{
gaiaFreeGeomColl (gaia);
return NULL;
}
return gaia;
}
GAIAGEO_DECLARE void *
gaiaToGeos (const gaiaGeomCollPtr gaia)
{
/* converting a GAIA Geometry into a GEOS Geometry */
return toGeosGeometry (NULL, NULL, gaia, GAIA2GEOS_ALL);
}
GAIAGEO_DECLARE void *
gaiaToGeos_r (const void *p_cache, const gaiaGeomCollPtr gaia)
{
/* converting a GAIA Geometry into a GEOS Geometry */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
return toGeosGeometry (cache, handle, gaia, GAIA2GEOS_ALL);
}
GAIAGEO_DECLARE void *
gaiaToGeosSelective (const gaiaGeomCollPtr gaia, int mode)
{
/* converting a GAIA Geometry into a GEOS Geometry (selected type) */
if (mode == GAIA2GEOS_ONLY_POINTS || mode == GAIA2GEOS_ONLY_LINESTRINGS
|| mode == GAIA2GEOS_ONLY_POLYGONS)
;
else
mode = GAIA2GEOS_ALL;
return toGeosGeometry (NULL, NULL, gaia, mode);
}
GAIAGEO_DECLARE void *
gaiaToGeosSelective_r (const void *p_cache, const gaiaGeomCollPtr gaia,
int mode)
{
/* converting a GAIA Geometry into a GEOS Geometry (selected type) */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
if (mode == GAIA2GEOS_ONLY_POINTS || mode == GAIA2GEOS_ONLY_LINESTRINGS
|| mode == GAIA2GEOS_ONLY_POLYGONS)
;
else
mode = GAIA2GEOS_ALL;
return toGeosGeometry (cache, handle, gaia, mode);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XY (const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XY] */
const GEOSGeometry *geos = xgeos;
return fromGeosGeometry (NULL, geos, GAIA_XY);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZ (const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYZ] */
const GEOSGeometry *geos = xgeos;
return fromGeosGeometry (NULL, geos, GAIA_XY_Z);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYM (const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYM] */
const GEOSGeometry *geos = xgeos;
return fromGeosGeometry (NULL, geos, GAIA_XY_M);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZM (const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYZM] */
const GEOSGeometry *geos = xgeos;
return fromGeosGeometry (NULL, geos, GAIA_XY_Z_M);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XY_r (const void *p_cache, const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XY] */
const GEOSGeometry *geos = xgeos;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
return fromGeosGeometry (handle, geos, GAIA_XY);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZ_r (const void *p_cache, const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYZ] */
const GEOSGeometry *geos = xgeos;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
return fromGeosGeometry (handle, geos, GAIA_XY_Z);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYM_r (const void *p_cache, const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYM] */
const GEOSGeometry *geos = xgeos;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
return fromGeosGeometry (handle, geos, GAIA_XY_M);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZM_r (const void *p_cache, const void *xgeos)
{
/* converting a GEOS Geometry into a GAIA Geometry [XYZM] */
const GEOSGeometry *geos = xgeos;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
return fromGeosGeometry (handle, geos, GAIA_XY_Z_M);
}
#endif /* end including GEOS */
libspatialite-5.1.0/src/gaiageo/gg_relations.c 0000644 0001750 0001750 00000376105 14463127014 016306 0000000 0000000 /*
gg_relations.c -- Gaia spatial relations
version 5.1.0, 2023 August 1
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#ifndef OMIT_GEOS /* including GEOS */
#ifdef GEOS_REENTRANT
#ifdef GEOS_ONLY_REENTRANT
#define GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
#endif
#endif
#include
#endif
#include
#include
#include
/* GLOBAL variables */
char *gaia_geos_error_msg = NULL;
char *gaia_geos_warning_msg = NULL;
char *gaia_geosaux_error_msg = NULL;
SPATIALITE_PRIVATE void
splite_free_geos_cache_item (struct splite_geos_cache_item *p)
{
#ifndef OMIT_GEOS /* including GEOS */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (p->preparedGeosGeom)
GEOSPreparedGeom_destroy (p->preparedGeosGeom);
if (p->geosGeom)
GEOSGeom_destroy (p->geosGeom);
#endif
#endif
p->geosGeom = NULL;
p->preparedGeosGeom = NULL;
}
SPATIALITE_PRIVATE void
splite_free_geos_cache_item_r (const void *p_cache,
struct splite_geos_cache_item *p)
{
#ifndef OMIT_GEOS /* including GEOS */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
{
splite_free_geos_cache_item (p);
return;
}
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
{
splite_free_geos_cache_item (p);
return;
}
handle = cache->GEOS_handle;
if (handle == NULL)
{
splite_free_geos_cache_item (p);
return;
}
if (p->preparedGeosGeom)
GEOSPreparedGeom_destroy_r (handle, p->preparedGeosGeom);
if (p->geosGeom)
GEOSGeom_destroy_r (handle, p->geosGeom);
#endif
p->geosGeom = NULL;
p->preparedGeosGeom = NULL;
}
GAIAGEO_DECLARE void
gaiaResetGeosMsg ()
{
/* resets the GEOS error and warning messages */
if (gaia_geos_error_msg != NULL)
free (gaia_geos_error_msg);
if (gaia_geos_warning_msg != NULL)
free (gaia_geos_warning_msg);
if (gaia_geosaux_error_msg != NULL)
free (gaia_geosaux_error_msg);
gaia_geos_error_msg = NULL;
gaia_geos_warning_msg = NULL;
gaia_geosaux_error_msg = NULL;
}
GAIAGEO_DECLARE const char *
gaiaGetGeosErrorMsg ()
{
/* return the latest GEOS error message */
return gaia_geos_error_msg;
}
GAIAGEO_DECLARE const char *
gaiaGetGeosWarningMsg ()
{
/* return the latest GEOS error message */
return gaia_geos_warning_msg;
}
GAIAGEO_DECLARE const char *
gaiaGetGeosAuxErrorMsg ()
{
/* return the latest GEOS (auxialiary) error message */
return gaia_geosaux_error_msg;
}
GAIAGEO_DECLARE void
gaiaSetGeosErrorMsg (const char *msg)
{
/* setting the latest GEOS error message */
int len;
if (gaia_geos_error_msg != NULL)
free (gaia_geos_error_msg);
gaia_geos_error_msg = NULL;
if (msg == NULL)
return;
len = strlen (msg);
gaia_geos_error_msg = malloc (len + 1);
strcpy (gaia_geos_error_msg, msg);
}
GAIAGEO_DECLARE void
gaiaSetGeosWarningMsg (const char *msg)
{
/* setting the latest GEOS error message */
int len;
if (gaia_geos_warning_msg != NULL)
free (gaia_geos_warning_msg);
gaia_geos_warning_msg = NULL;
if (msg == NULL)
return;
len = strlen (msg);
gaia_geos_warning_msg = malloc (len + 1);
strcpy (gaia_geos_warning_msg, msg);
}
GAIAGEO_DECLARE void
gaiaSetGeosAuxErrorMsg (const char *msg)
{
/* setting the latest GEOS (auxiliary) error message */
int len;
if (gaia_geosaux_error_msg != NULL)
free (gaia_geosaux_error_msg);
gaia_geosaux_error_msg = NULL;
if (msg == NULL)
return;
len = strlen (msg);
gaia_geosaux_error_msg = malloc (len + 1);
strcpy (gaia_geosaux_error_msg, msg);
}
static int
check_point (double *coords, int points, double x, double y)
{
/* checks if [X,Y] point is defined into this coordinate array [Linestring or Ring] */
int iv;
double xx;
double yy;
for (iv = 0; iv < points; iv++)
{
gaiaGetPoint (coords, iv, &xx, &yy);
if (xx == x && yy == y)
return 1;
}
return 0;
}
GAIAGEO_DECLARE int
gaiaLinestringEquals (gaiaLinestringPtr line1, gaiaLinestringPtr line2)
{
/* checks if two Linestrings are "spatially equal" */
int iv;
double x;
double y;
if (line1->Points != line2->Points)
return 0;
for (iv = 0; iv < line1->Points; iv++)
{
gaiaGetPoint (line1->Coords, iv, &x, &y);
if (!check_point (line2->Coords, line2->Points, x, y))
return 0;
}
return 1;
}
GAIAGEO_DECLARE int
gaiaPolygonEquals (gaiaPolygonPtr polyg1, gaiaPolygonPtr polyg2)
{
/* checks if two Polygons are "spatially equal" */
int ib;
int ib2;
int iv;
int ok2;
double x;
double y;
gaiaRingPtr ring1;
gaiaRingPtr ring2;
if (polyg1->NumInteriors != polyg2->NumInteriors)
return 0;
/* checking the EXTERIOR RINGs */
ring1 = polyg1->Exterior;
ring2 = polyg2->Exterior;
if (ring1->Points != ring2->Points)
return 0;
for (iv = 0; iv < ring1->Points; iv++)
{
gaiaGetPoint (ring1->Coords, iv, &x, &y);
if (!check_point (ring2->Coords, ring2->Points, x, y))
return 0;
}
for (ib = 0; ib < polyg1->NumInteriors; ib++)
{
/* checking the INTERIOR RINGS */
int ok = 0;
ring1 = polyg1->Interiors + ib;
for (ib2 = 0; ib2 < polyg2->NumInteriors; ib2++)
{
ok2 = 1;
ring2 = polyg2->Interiors + ib2;
for (iv = 0; iv < ring1->Points; iv++)
{
gaiaGetPoint (ring1->Coords, iv, &x, &y);
if (!check_point (ring2->Coords, ring2->Points, x, y))
{
ok2 = 0;
break;
}
}
if (ok2)
{
ok = 1;
break;
}
}
if (!ok)
return 0;
}
return 1;
}
#ifndef OMIT_GEOS /* including GEOS */
static int
splite_mbr_overlaps (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if two MBRs do overlap */
if (g1->MaxX < g2->MinX)
return 0;
if (g1->MinX > g2->MaxX)
return 0;
if (g1->MaxY < g2->MinY)
return 0;
if (g1->MinY > g2->MaxY)
return 0;
return 1;
}
static int
splite_mbr_contains (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if MBR#1 fully contains MBR#2 */
if (g2->MinX < g1->MinX)
return 0;
if (g2->MaxX > g1->MaxX)
return 0;
if (g2->MinY < g1->MinY)
return 0;
if (g2->MaxY > g1->MaxY)
return 0;
return 1;
}
static int
splite_mbr_within (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if MBR#1 is fully contained within MBR#2 */
if (g1->MinX < g2->MinX)
return 0;
if (g1->MaxX > g2->MaxX)
return 0;
if (g1->MinY < g2->MinY)
return 0;
if (g1->MaxY > g2->MaxY)
return 0;
return 1;
}
static int
splite_mbr_equals (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if MBR#1 equals MBR#2 */
if (g1->MinX != g2->MinX)
return 0;
if (g1->MaxX != g2->MaxX)
return 0;
if (g1->MinY != g2->MinY)
return 0;
if (g1->MaxY != g2->MaxY)
return 0;
return 1;
}
static int
evalGeosCacheItem (unsigned char *blob, int blob_size, uLong crc,
struct splite_geos_cache_item *p)
{
/* evaluting if this one could be a valid cache hit */
if (blob_size != p->gaiaBlobSize)
{
/* surely not a match; different size */
return 0;
}
if (crc != p->crc32)
{
/* surely not a match: different CRC32 */
return 0;
}
/* the first 46 bytes of the BLOB contain the MBR,
the SRID and the Type; so are assumed to represent
a valid signature */
if (memcmp (blob, p->gaiaBlob, 46) == 0)
return 1;
return 0;
}
static int
sniffTinyPointBlob (const unsigned char *blob, const int size)
{
/* sniffing for a possible TinyPoint BLOB */
if (size == 24 || size == 32 || size == 40)
;
else
return 0;
if (*(blob + 0) != GAIA_MARK_START)
return 0;
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
;
else
return 0;
if (*(blob + (size - 1)) != GAIA_MARK_END)
return 0;
return 1;
}
static void
tinyPoint2Geom (const unsigned char *tiny, unsigned char **geom, int *geom_sz)
{
/* quickly converting from BLOB-TinyPoint to BLOB-Geometry */
int little_endian;
int endian_arch = gaiaEndianArch ();
int srid;
int type;
double x;
double y;
double z;
double m;
unsigned char *blob;
int blob_sz;
/* parsing the BLOB-TinyPoint */
if (*(tiny + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else
little_endian = 0;
srid = gaiaImport32 (tiny + 2, little_endian, endian_arch);
if (*(tiny + 6) == GAIA_TINYPOINT_XYZ)
type = GAIA_POINTZ;
else if (*(tiny + 6) == GAIA_TINYPOINT_XYM)
type = GAIA_POINTM;
else if (*(tiny + 6) == GAIA_TINYPOINT_XYZM)
type = GAIA_POINTZM;
else
type = GAIA_POINT;
x = gaiaImport64 (tiny + 7, little_endian, endian_arch);
y = gaiaImport64 (tiny + 15, little_endian, endian_arch);
if (type == GAIA_POINTZ)
z = gaiaImport64 (tiny + 23, little_endian, endian_arch);
if (type == GAIA_POINTM)
m = gaiaImport64 (tiny + 23, little_endian, endian_arch);
if (type == GAIA_POINTZM)
{
z = gaiaImport64 (tiny + 23, little_endian, endian_arch);
m = gaiaImport64 (tiny + 31, little_endian, endian_arch);
}
/* allocating and initializing the BLOB-Geometry */
switch (type)
{
case GAIA_POINT:
blob_sz = 60;
break;
case GAIA_POINTZ:
case GAIA_POINTM:
blob_sz = 68;
break;
case GAIA_POINTZM:
blob_sz = 76;
break;
};
blob = malloc (blob_sz);
*geom = blob;
*geom_sz = blob_sz;
switch (type)
{
case GAIA_POINT:
*blob = GAIA_MARK_START; /* START signature */
*(blob + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (blob + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (blob + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (blob + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (blob + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (blob + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(blob + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (blob + 39, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (blob + 43, x, 1, endian_arch); /* X */
gaiaExport64 (blob + 51, y, 1, endian_arch); /* Y */
*(blob + 59) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZ:
*blob = GAIA_MARK_START; /* START signature */
*(blob + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (blob + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (blob + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (blob + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (blob + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (blob + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(blob + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (blob + 39, GAIA_POINTZ, 1, endian_arch); /* class POINT XYZ */
gaiaExport64 (blob + 43, x, 1, endian_arch); /* X */
gaiaExport64 (blob + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (blob + 59, z, 1, endian_arch); /* Z */
*(blob + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTM:
*blob = GAIA_MARK_START; /* START signature */
*(blob + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (blob + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (blob + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (blob + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (blob + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (blob + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(blob + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (blob + 39, GAIA_POINTM, 1, endian_arch); /* class POINT XYM */
gaiaExport64 (blob + 43, x, 1, endian_arch); /* X */
gaiaExport64 (blob + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (blob + 59, m, 1, endian_arch); /* M */
*(blob + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZM:
*blob = GAIA_MARK_START; /* START signature */
*(blob + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (blob + 2, srid, 1, endian_arch); /* the SRID */
gaiaExport64 (blob + 6, x, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (blob + 14, y, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (blob + 22, x, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (blob + 30, y, 1, endian_arch); /* MBR - maximum Y */
*(blob + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (blob + 39, GAIA_POINTZM, 1, endian_arch); /* class POINT XYZM */
gaiaExport64 (blob + 43, x, 1, endian_arch); /* X */
gaiaExport64 (blob + 51, y, 1, endian_arch); /* Y */
gaiaExport64 (blob + 59, z, 1, endian_arch); /* M */
gaiaExport64 (blob + 67, m, 1, endian_arch); /* Z */
*(blob + 75) = GAIA_MARK_END; /* END signature */
break;
};
}
static int
evalGeosCache (struct splite_internal_cache *cache, gaiaGeomCollPtr geom1,
const unsigned char *blob1, const int size1,
gaiaGeomCollPtr geom2, const unsigned char *blob2,
const int size2, GEOSPreparedGeometry ** gPrep,
gaiaGeomCollPtr * geom)
{
/* handling the internal GEOS cache */
struct splite_geos_cache_item *p1 = &(cache->cacheItem1);
struct splite_geos_cache_item *p2 = &(cache->cacheItem2);
uLong crc1;
uLong crc2;
unsigned char *tiny1 = NULL;
unsigned char *tiny2 = NULL;
unsigned char *p_blob1;
unsigned char *p_blob2;
int sz1;
int sz2;
int tiny_sz;
int retcode;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
if (sniffTinyPointBlob (blob1, size1))
{
tinyPoint2Geom (blob1, &tiny1, &tiny_sz);
p_blob1 = tiny1;
sz1 = tiny_sz;
}
else
{
p_blob1 = (unsigned char *) blob1;
sz1 = size1;
}
if (sniffTinyPointBlob (blob2, size2))
{
tinyPoint2Geom (blob2, &tiny2, &tiny_sz);
p_blob2 = tiny2;
sz2 = tiny_sz;
}
else
{
p_blob2 = (unsigned char *) blob2;
sz2 = size2;
}
crc1 = crc32 (0L, p_blob1, sz1);
crc2 = crc32 (0L, p_blob2, sz2);
/* checking the first cache item */
if (evalGeosCacheItem (p_blob1, sz1, crc1, p1))
{
/* found a matching item */
if (p1->preparedGeosGeom == NULL)
{
/* preparing the GeosGeometries */
p1->geosGeom = gaiaToGeos_r (cache, geom1);
if (p1->geosGeom)
{
p1->preparedGeosGeom =
(void *) GEOSPrepare_r (handle, p1->geosGeom);
if (p1->preparedGeosGeom == NULL)
{
/* unexpected failure */
GEOSGeom_destroy_r (handle, p1->geosGeom);
p1->geosGeom = NULL;
}
}
}
if (p1->preparedGeosGeom)
{
/* returning the corresponding GeosPreparedGeometry */
*gPrep = p1->preparedGeosGeom;
*geom = geom2;
retcode = 1;
goto end;
}
retcode = 0;
goto end;
}
/* checking the second cache item */
if (evalGeosCacheItem (p_blob2, sz2, crc2, p2))
{
/* found a matching item */
if (p2->preparedGeosGeom == NULL)
{
/* preparing the GeosGeometries */
p2->geosGeom = gaiaToGeos_r (cache, geom2);
if (p2->geosGeom)
{
p2->preparedGeosGeom =
(void *) GEOSPrepare_r (handle, p2->geosGeom);
if (p2->preparedGeosGeom == NULL)
{
/* unexpected failure */
GEOSGeom_destroy_r (handle, p2->geosGeom);
p2->geosGeom = NULL;
}
}
}
if (p2->preparedGeosGeom)
{
/* returning the corresponding GeosPreparedGeometry */
*gPrep = p2->preparedGeosGeom;
*geom = geom1;
retcode = 1;
goto end;
}
retcode = 0;
goto end;
}
/* updating the GEOS cache item#1 */
memcpy (p1->gaiaBlob, p_blob1, 46);
p1->gaiaBlobSize = sz1;
p1->crc32 = crc1;
if (p1->preparedGeosGeom)
GEOSPreparedGeom_destroy_r (handle, p1->preparedGeosGeom);
if (p1->geosGeom)
GEOSGeom_destroy_r (handle, p1->geosGeom);
p1->geosGeom = NULL;
p1->preparedGeosGeom = NULL;
/* updating the GEOS cache item#2 */
memcpy (p2->gaiaBlob, p_blob2, 46);
p2->gaiaBlobSize = sz2;
p2->crc32 = crc2;
if (p2->preparedGeosGeom)
GEOSPreparedGeom_destroy_r (handle, p2->preparedGeosGeom);
if (p2->geosGeom)
GEOSGeom_destroy_r (handle, p2->geosGeom);
p2->geosGeom = NULL;
p2->preparedGeosGeom = NULL;
retcode = 0;
end:
if (tiny1 != NULL)
free (tiny1);
if (tiny2 != NULL)
free (tiny2);
return retcode;
}
GAIAGEO_DECLARE int
gaiaGeomCollEquals (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries are "spatially equal" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_equals (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSEquals (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollEquals_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries are "spatially equal" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_equals (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSEquals_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollIntersects (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially intersects" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSIntersects (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollIntersects_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially intersects" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSIntersects_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedIntersects (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if two Geometries do "spatially intersects" */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedIntersects_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSIntersects_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollDisjoint (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries are "spatially disjoint" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 1;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSDisjoint (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollDisjoint_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries are "spatially disjoint" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 1;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSDisjoint_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedDisjoint (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if two Geometries are "spatially disjoint" */
int ret;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 1;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedDisjoint_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSDisjoint_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollOverlaps (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially overlaps" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSOverlaps (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollOverlaps_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially overlaps" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSOverlaps_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedOverlaps (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if two Geometries do "spatially overlaps" */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedOverlaps_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSOverlaps_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollCrosses (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially crosses" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSCrosses (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollCrosses_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially crosses" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCrosses_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedCrosses (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if two Geometries do "spatially crosses" */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedCrosses_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCrosses_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollTouches (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially touches" */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSTouches (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollTouches_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if two Geometries do "spatially touches" */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSTouches_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedTouches (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if two Geometries do "spatially touches" */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSPreparedGeometry *gPrep;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedTouches_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSTouches_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollWithin (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if GEOM-1 is completely contained within GEOM-2 */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSWithin (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollWithin_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if GEOM-1 is completely contained within GEOM-2 */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSWithin_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedWithin (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if GEOM-1 is completely contained within GEOM-2 */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
if (geom == geom2)
ret = GEOSPreparedWithin_r (handle, gPrep, g2);
else
ret = GEOSPreparedContains_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSWithin_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollContains (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if GEOM-1 completely contains GEOM-2 */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSContains (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollContains_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if GEOM-1 completely contains GEOM-2 */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSContains_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedContains (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if GEOM-1 completely contains GEOM-2 */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
if (geom == geom2)
ret = GEOSPreparedContains_r (handle, gPrep, g2);
else
ret = GEOSPreparedWithin_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSContains_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollRelate (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
const char *pattern)
{
/* checks if if GEOM-1 and GEOM-2 have a spatial relationship as specified by the pattern Matrix */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return -1;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSRelatePattern (g1, g2, pattern);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret == 2)
return -1;
#else
if (geom1 == NULL || geom2 == NULL || pattern == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollRelate_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, const char *pattern)
{
/* checks if if GEOM-1 and GEOM-2 have a spatial relationship as specified by the pattern Matrix */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return -1;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSRelatePattern_r (handle, g1, g2, pattern);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE char *
gaiaGeomCollRelateBoundaryNodeRule (gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, int mode)
{
/* return the intesection matrix [DE-9IM] of GEOM-1 and GEOM-2 */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
int bnr;
char *retMatrix;
char *matrix;
int len;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
switch (mode)
{
case 2:
bnr = GEOSRELATE_BNR_ENDPOINT;
break;
case 3:
bnr = GEOSRELATE_BNR_MULTIVALENT_ENDPOINT;
break;
case 4:
bnr = GEOSRELATE_BNR_MONOVALENT_ENDPOINT;
break;
default:
bnr = GEOSRELATE_BNR_MOD2;
break;
};
retMatrix = GEOSRelateBoundaryNodeRule (g1, g2, bnr);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (retMatrix == NULL)
return NULL;
len = strlen (retMatrix);
matrix = malloc (len + 1);
strcpy (matrix, retMatrix);
GEOSFree (retMatrix);
return matrix;
#else
if (geom1 == NULL || geom2 == NULL || mode == 0)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return NULL;
}
GAIAGEO_DECLARE char *
gaiaGeomCollRelateBoundaryNodeRule_r (const void *p_cache,
gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, int mode)
{
/* return the intesection matrix [DE-9IM] of GEOM-1 and GEOM-2 */
GEOSGeometry *g1;
GEOSGeometry *g2;
int bnr;
char *retMatrix;
char *matrix;
int len;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
switch (mode)
{
case 2:
bnr = GEOSRELATE_BNR_ENDPOINT;
break;
case 3:
bnr = GEOSRELATE_BNR_MULTIVALENT_ENDPOINT;
break;
case 4:
bnr = GEOSRELATE_BNR_MONOVALENT_ENDPOINT;
break;
default:
bnr = GEOSRELATE_BNR_MOD2;
break;
};
retMatrix = GEOSRelateBoundaryNodeRule_r (handle, g1, g2, bnr);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (retMatrix == NULL)
return NULL;
len = strlen (retMatrix);
matrix = malloc (len + 1);
strcpy (matrix, retMatrix);
GEOSFree_r (handle, retMatrix);
return matrix;
}
GAIAGEO_DECLARE int
gaiaIntersectionMatrixPatternMatch (const char *matrix, const char *pattern)
{
/* evalutes if an intersection matrix [DE-9IM] matches a matrix pattern */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
int ret;
gaiaResetGeosMsg ();
if (matrix == NULL || pattern == NULL)
return -1;
ret = GEOSRelatePatternMatch (matrix, pattern);
if (ret == 0 || ret == 1)
return ret;
#else
if (matrix == NULL || pattern == NULL)
matrix = NULL; /* silencing stupid compiler warnings */
#endif
return -1;
}
GAIAGEO_DECLARE int
gaiaIntersectionMatrixPatternMatch_r (const void *p_cache, const char *matrix,
const char *pattern)
{
/* evalutes is an intersection matrix [DE-9IM] matches a matrix pattern */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (matrix == NULL || pattern == NULL)
return -1;
ret = GEOSRelatePatternMatch_r (handle, matrix, pattern);
if (ret == 0 || ret == 1)
return ret;
return -1;
}
GAIAGEO_DECLARE int
gaiaGeomCollLength (gaiaGeomCollPtr geom, double *xlength)
{
/* computes the total length for this Geometry */
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double length;
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!geom)
return 0;
if (gaiaIsToxic (geom))
return 0;
g = gaiaToGeos (geom);
ret = GEOSLength (g, &length);
GEOSGeom_destroy (g);
if (ret)
*xlength = length;
#else
if (geom == NULL || xlength == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollLength_r (const void *p_cache, gaiaGeomCollPtr geom,
double *xlength)
{
/* computes the total length for this Geometry */
double length;
int ret;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
if (gaiaIsToxic_r (cache, geom))
return 0;
g = gaiaToGeos_r (cache, geom);
ret = GEOSLength_r (handle, g, &length);
GEOSGeom_destroy_r (handle, g);
if (ret)
*xlength = length;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollLengthOrPerimeter (gaiaGeomCollPtr geom, int perimeter,
double *xlength)
{
/* computes the total length or perimeter for this Geometry */
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double length;
GEOSGeometry *g;
int mode = GAIA2GEOS_ONLY_LINESTRINGS;
if (perimeter)
mode = GAIA2GEOS_ONLY_POLYGONS;
gaiaResetGeosMsg ();
if (!geom)
return 0;
if (gaiaIsToxic (geom))
return 0;
g = gaiaToGeosSelective (geom, mode);
if (g == NULL)
{
*xlength = 0.0;
return 1;
}
ret = GEOSLength (g, &length);
GEOSGeom_destroy (g);
if (ret)
*xlength = length;
#else
if (geom == NULL || perimeter == 0 || xlength == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollLengthOrPerimeter_r (const void *p_cache, gaiaGeomCollPtr geom,
int perimeter, double *xlength)
{
/* computes the total length or perimeter for this Geometry */
double length;
int ret;
int mode = GAIA2GEOS_ONLY_LINESTRINGS;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
if (perimeter)
mode = GAIA2GEOS_ONLY_POLYGONS;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
if (gaiaIsToxic_r (cache, geom))
return 0;
g = gaiaToGeosSelective_r (cache, geom, mode);
if (g == NULL)
{
*xlength = 0.0;
return 1;
}
ret = GEOSLength_r (handle, g, &length);
GEOSGeom_destroy_r (handle, g);
if (ret)
*xlength = length;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollArea (gaiaGeomCollPtr geom, double *xarea)
{
/* computes the total area for this Geometry */
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double area;
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!geom)
return 0;
if (gaiaIsToxic (geom))
return 0;
g = gaiaToGeos (geom);
ret = GEOSArea (g, &area);
GEOSGeom_destroy (g);
if (ret)
*xarea = area;
#else
if (geom == NULL || xarea == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollArea_r (const void *p_cache, gaiaGeomCollPtr geom, double *xarea)
{
/* computes the total area for this Geometry */
double area;
int ret;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
if (gaiaIsToxic_r (cache, geom))
return 0;
g = gaiaToGeos_r (cache, geom);
ret = GEOSArea_r (handle, g, &area);
GEOSGeom_destroy_r (handle, g);
if (ret)
*xarea = area;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollDistance (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double *xdist)
{
/* computes the minimum distance intercurring between GEOM-1 and GEOM-2 */
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double dist;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return 0;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSDistance (g1, g2, &dist);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret)
*xdist = dist;
#else
if (geom1 == NULL || geom2 == NULL || xdist == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollDistance_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *xdist)
{
/* computes the minimum distance intercurring between GEOM-1 and GEOM-2 */
double dist;
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSDistance_r (handle, g1, g2, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
#ifdef GEOS_3100 /* only if GEOS_3100 support is available */
GAIAGEO_DECLARE int
gaiaGeomCollPreparedDistance (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2, double *xdist)
{
/* computes the minimum distance intercurring between GEOM-1 and GEOM-2 */
double dist;
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedDistance_r (handle, gPrep, g2, &dist);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSDistance_r (handle, g1, g2, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedDistanceWithin (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2, double dist)
{
/* Test whether the distance between two geometries is within the given dist. */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
ret = GEOSPreparedDistanceWithin_r (handle, gPrep, g2, dist);
GEOSGeom_destroy_r (handle, g2);
if (ret)
return 1;
return 0;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSDistanceWithin_r (handle, g1, g2, dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
return 1;
return 0;
}
#endif /* end GEOS_3100 conditional */
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryIntersection (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial intersection" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return NULL;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
g3 = GEOSIntersection (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (!g3)
return NULL;
if (GEOSisEmpty (g3) == 1)
{
GEOSGeom_destroy (g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g3);
else
geo = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryIntersection_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial intersection" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return NULL;
/* quick check based on MBRs comparison */
if (!splite_mbr_overlaps (geom1, geom2))
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
g3 = GEOSIntersection_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (!g3)
return NULL;
if (GEOSisEmpty_r (handle, g3) == 1)
{
GEOSGeom_destroy_r (handle, g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g3);
else
geo = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryUnion (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial union" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
g3 = GEOSUnion (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (g3 == NULL)
return NULL;
if (GEOSisEmpty (g3) == 1)
{
GEOSGeom_destroy (g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g3);
else
geo = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
if (geo->DeclaredType == GAIA_POINT &&
geom1->DeclaredType == GAIA_MULTIPOINT)
geo->DeclaredType = GAIA_MULTIPOINT;
if (geo->DeclaredType == GAIA_LINESTRING &&
geom1->DeclaredType == GAIA_MULTILINESTRING)
geo->DeclaredType = GAIA_MULTILINESTRING;
if (geo->DeclaredType == GAIA_POLYGON &&
geom1->DeclaredType == GAIA_MULTIPOLYGON)
geo->DeclaredType = GAIA_MULTIPOLYGON;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryUnion_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial union" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
g3 = GEOSUnion_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (g3 == NULL)
return NULL;
if (GEOSisEmpty_r (handle, g3) == 1)
{
GEOSGeom_destroy_r (handle, g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g3);
else
geo = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
if (geo->DeclaredType == GAIA_POINT &&
geom1->DeclaredType == GAIA_MULTIPOINT)
geo->DeclaredType = GAIA_MULTIPOINT;
if (geo->DeclaredType == GAIA_LINESTRING &&
geom1->DeclaredType == GAIA_MULTILINESTRING)
geo->DeclaredType = GAIA_MULTILINESTRING;
if (geo->DeclaredType == GAIA_POLYGON &&
geom1->DeclaredType == GAIA_MULTIPOLYGON)
geo->DeclaredType = GAIA_MULTIPOLYGON;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaUnionCascaded (gaiaGeomCollPtr geom)
{
/* UnionCascaded (single Collection of polygons) */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
/* testing if geom only contains Polygons */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts || lns)
return NULL;
if (!pgs)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSUnionCascaded (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaUnionCascaded_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* UnionCascaded (single Collection of polygons) */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
/* testing if geom only contains Polygons */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts || lns)
return NULL;
if (!pgs)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSUnionCascaded_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryDifference (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial difference" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
g3 = GEOSDifference (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (!g3)
return NULL;
if (GEOSisEmpty (g3) == 1)
{
GEOSGeom_destroy (g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g3);
else
geo = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometryDifference_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial difference" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
g3 = GEOSDifference_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (!g3)
return NULL;
if (GEOSisEmpty_r (handle, g3) == 1)
{
GEOSGeom_destroy_r (handle, g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g3);
else
geo = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometrySymDifference (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial symmetric difference" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic (geom1) || gaiaIsToxic (geom2))
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
g3 = GEOSSymDifference (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (!g3)
return NULL;
if (GEOSisEmpty (g3) == 1)
{
GEOSGeom_destroy (g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g3);
else
geo = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeometrySymDifference_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* builds a new geometry representing the "spatial symmetric difference" of GEOM-1 and GEOM-2 */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
if (gaiaIsToxic_r (cache, geom1) || gaiaIsToxic_r (cache, geom2))
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
g3 = GEOSSymDifference_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (!g3)
return NULL;
if (GEOSisEmpty_r (handle, g3) == 1)
{
GEOSGeom_destroy_r (handle, g3);
return NULL;
}
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g3);
else
geo = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaBoundary (gaiaGeomCollPtr geom)
{
/* builds a new geometry representing the combinatorial boundary of GEOM */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSBoundary (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaBoundary_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* builds a new geometry representing the combinatorial boundary of GEOM */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSBoundary_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE int
gaiaGeomCollCentroid (gaiaGeomCollPtr geom, double *x, double *y)
{
/* returns a Point representing the centroid for this Geometry */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return 0;
if (gaiaIsToxic (geom))
{
return 0;
}
g1 = gaiaToGeos (geom);
g2 = GEOSGetCentroid (g1);
GEOSGeom_destroy (g1);
if (!g2)
return 0;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return 0;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return 0;
if (geo->FirstPoint)
{
*x = geo->FirstPoint->X;
*y = geo->FirstPoint->Y;
gaiaFreeGeomColl (geo);
return 1;
}
gaiaFreeGeomColl (geo);
#else
if (geom == NULL || x == NULL || y == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return 0;
}
GAIAGEO_DECLARE int
gaiaGeomCollCentroid_r (const void *p_cache, gaiaGeomCollPtr geom, double *x,
double *y)
{
/* returns a Point representing the centroid for this Geometry */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
if (gaiaIsToxic_r (cache, geom))
{
return 0;
}
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSGetCentroid_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return 0;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return 0;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return 0;
if (geo->FirstPoint)
{
*x = geo->FirstPoint->X;
*y = geo->FirstPoint->Y;
gaiaFreeGeomColl (geo);
return 1;
}
gaiaFreeGeomColl (geo);
return 0;
}
GAIAGEO_DECLARE int
gaiaGetPointOnSurface (gaiaGeomCollPtr geom, double *x, double *y)
{
/* returns a Point guaranteed to lie on the Surface */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return 0;
if (gaiaIsToxic (geom))
{
return 0;
}
g1 = gaiaToGeos (geom);
g2 = GEOSPointOnSurface (g1);
GEOSGeom_destroy (g1);
if (!g2)
return 0;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return 0;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return 0;
if (geo->FirstPoint)
{
*x = geo->FirstPoint->X;
*y = geo->FirstPoint->Y;
gaiaFreeGeomColl (geo);
return 1;
}
gaiaFreeGeomColl (geo);
#else
if (geom == NULL || x == NULL || y == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return 0;
}
GAIAGEO_DECLARE int
gaiaGetPointOnSurface_r (const void *p_cache, gaiaGeomCollPtr geom, double *x,
double *y)
{
/* returns a Point guaranteed to lie on the Surface */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
if (gaiaIsToxic_r (cache, geom))
{
return 0;
}
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSPointOnSurface_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return 0;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return 0;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XYZ_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return 0;
if (geo->FirstPoint)
{
*x = geo->FirstPoint->X;
*y = geo->FirstPoint->Y;
gaiaFreeGeomColl (geo);
return 1;
}
gaiaFreeGeomColl (geo);
return 0;
}
GAIAGEO_DECLARE int
gaiaIsSimple (gaiaGeomCollPtr geom)
{
/* checks if this GEOMETRYCOLLECTION is a simple one */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!geom)
return -1;
if (gaiaIsToxic (geom))
return 0;
g = gaiaToGeos (geom);
ret = GEOSisSimple (g);
GEOSGeom_destroy (g);
if (ret == 2)
return -1;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaIsSimple_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* checks if this GEOMETRYCOLLECTION is a simple one */
int ret;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom)
return -1;
if (gaiaIsToxic_r (cache, geom))
return -1;
g = gaiaToGeos_r (cache, geom);
ret = GEOSisSimple_r (handle, g);
GEOSGeom_destroy_r (handle, g);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaIsRing (gaiaLinestringPtr line)
{
/* checks if this LINESTRING can be a valid RING */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaiaGeomCollPtr geo;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
double m;
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!line)
return -1;
if (line->DimensionModel == GAIA_XY_Z)
geo = gaiaAllocGeomCollXYZ ();
else if (line->DimensionModel == GAIA_XY_M)
geo = gaiaAllocGeomCollXYM ();
else if (line->DimensionModel == GAIA_XY_Z_M)
geo = gaiaAllocGeomCollXYZM ();
else
geo = gaiaAllocGeomColl ();
line2 = gaiaAddLinestringToGeomColl (geo, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
z = 0.0;
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);
}
if (line2->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
else if (line2->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line2->Coords, iv, x, y, m);
}
else if (line2->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line2->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line2->Coords, iv, x, y);
}
}
if (gaiaIsToxic (geo))
{
gaiaFreeGeomColl (geo);
return -1;
}
g = gaiaToGeos (geo);
gaiaFreeGeomColl (geo);
ret = GEOSisRing (g);
GEOSGeom_destroy (g);
if (ret == 2)
return -1;
#else
if (line == NULL)
line = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaIsRing_r (const void *p_cache, gaiaLinestringPtr line)
{
/* checks if this LINESTRING can be a valid RING */
gaiaGeomCollPtr geo;
gaiaLinestringPtr line2;
int ret;
int iv;
double x;
double y;
double z;
double m;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!line)
return -1;
if (line->DimensionModel == GAIA_XY_Z)
geo = gaiaAllocGeomCollXYZ ();
else if (line->DimensionModel == GAIA_XY_M)
geo = gaiaAllocGeomCollXYM ();
else if (line->DimensionModel == GAIA_XY_Z_M)
geo = gaiaAllocGeomCollXYZM ();
else
geo = gaiaAllocGeomColl ();
line2 = gaiaAddLinestringToGeomColl (geo, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
z = 0.0;
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);
}
if (line2->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
else if (line2->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line2->Coords, iv, x, y, m);
}
else if (line2->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line2->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line2->Coords, iv, x, y);
}
}
if (gaiaIsToxic_r (cache, geo))
{
gaiaFreeGeomColl (geo);
return -1;
}
g = gaiaToGeos_r (cache, geo);
gaiaFreeGeomColl (geo);
ret = GEOSisRing_r (handle, g);
GEOSGeom_destroy_r (handle, g);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaIsValid (gaiaGeomCollPtr geom)
{
/* checks if this GEOMETRYCOLLECTION is a valid one */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!geom)
return -1;
if (gaiaIsToxic (geom))
return 0;
if (gaiaIsNotClosedGeomColl (geom))
return 0;
g = gaiaToGeos (geom);
ret = GEOSisValid (g);
GEOSGeom_destroy (g);
if (ret == 2)
return -1;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaIsValid_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* checks if this GEOMETRYCOLLECTION is a valid one */
int ret;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom)
return -1;
if (gaiaIsToxic_r (cache, geom))
return 0;
if (gaiaIsNotClosedGeomColl_r (cache, geom))
return 0;
g = gaiaToGeos_r (cache, geom);
ret = GEOSisValid_r (handle, g);
GEOSGeom_destroy_r (handle, g);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE char *
gaiaIsValidReason (gaiaGeomCollPtr geom)
{
/* return a TEXT string stating if a Geometry is valid
/ and if not valid, a reason why */
char *text = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
int len;
const char *str;
char *gstr;
GEOSGeometry *g;
gaiaResetGeosMsg ();
if (!geom)
{
str = "Invalid: NULL Geometry";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
if (gaiaIsToxic (geom))
{
str = "Invalid: Toxic Geometry ... too few points";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
if (gaiaIsNotClosedGeomColl (geom))
{
str = "Invalid: Unclosed Rings were detected";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
g = gaiaToGeos (geom);
gstr = GEOSisValidReason (g);
GEOSGeom_destroy (g);
if (gstr == NULL)
return NULL;
len = strlen (gstr);
text = malloc (len + 1);
strcpy (text, gstr);
GEOSFree (gstr);
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return text;
}
GAIAGEO_DECLARE char *
gaiaIsValidReason_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* return a TEXT string stating if a Geometry is valid
/ and if not valid, a reason why */
char *text;
int len;
const char *str;
char *gstr;
GEOSGeometry *g;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
{
str = "Invalid: NULL Geometry";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
if (gaiaIsToxic_r (cache, geom))
{
str = "Invalid: Toxic Geometry ... too few points";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
if (gaiaIsNotClosedGeomColl_r (cache, geom))
{
str = "Invalid: Unclosed Rings were detected";
len = strlen (str);
text = malloc (len + 1);
strcpy (text, str);
return text;
}
g = gaiaToGeos_r (cache, geom);
gstr = GEOSisValidReason_r (handle, g);
GEOSGeom_destroy_r (handle, g);
if (gstr == NULL)
return NULL;
len = strlen (gstr);
text = malloc (len + 1);
strcpy (text, gstr);
GEOSFree_r (handle, gstr);
return text;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaIsValidDetailEx (gaiaGeomCollPtr geom, int esri_flag)
{
/* return a Geometry detail causing a Geometry to be invalid */
gaiaGeomCollPtr detail = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
char *reason = NULL;
GEOSGeometry *g;
GEOSGeometry *d = NULL;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
if (gaiaIsNotClosedGeomColl (geom))
return NULL;
g = gaiaToGeos (geom);
if (esri_flag)
esri_flag = GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE;
GEOSisValidDetail (g, esri_flag, &reason, &d);
GEOSGeom_destroy (g);
if (reason != NULL)
GEOSFree (reason);
if (d == NULL)
return NULL;
detail = gaiaFromGeos_XY (d);
GEOSGeom_destroy (d);
#else
if (geom == NULL && esri_flag == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return detail;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaIsValidDetail (gaiaGeomCollPtr geom)
{
/* return a Geometry detail causing a Geometry to be invalid */
return gaiaIsValidDetailEx (geom, 0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaIsValidDetailEx_r (const void *p_cache, gaiaGeomCollPtr geom, int esri_flag)
{
/* return a Geometry detail causing a Geometry to be invalid */
char *reason = NULL;
GEOSGeometry *g;
GEOSGeometry *d = NULL;
gaiaGeomCollPtr detail;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
if (gaiaIsNotClosedGeomColl_r (cache, geom))
return NULL;
g = gaiaToGeos_r (cache, geom);
if (esri_flag)
esri_flag = GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE;
GEOSisValidDetail_r (handle, g, esri_flag, &reason, &d);
GEOSGeom_destroy_r (handle, g);
if (reason != NULL)
GEOSFree_r (handle, reason);
if (d == NULL)
return NULL;
detail = gaiaFromGeos_XY_r (cache, d);
GEOSGeom_destroy_r (handle, d);
return detail;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaIsValidDetail_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* return a Geometry detail causing a Geometry to be invalid */
return gaiaIsValidDetailEx_r (p_cache, geom, 0);
}
GAIAGEO_DECLARE int
gaiaIsClosedGeom_r (const void *cache, gaiaGeomCollPtr geom)
{
/* checks if this geometry is a closed linestring (or multilinestring) */
int ret = 0;
gaiaLinestringPtr ln;
if (cache != NULL)
gaiaResetGeosMsg_r (cache);
if (!geom)
return -1;
if (cache != NULL)
ret = gaiaIsToxic_r (cache, geom);
else
ret = gaiaIsToxic (geom);
if (ret)
return 0;
ln = geom->FirstLinestring;
while (ln)
{
/* unhappily GEOS v3.2.2 [system package on Debian Lenny and Ubuntu 12.04]
* doesn't exposes the GEOSisClosed() API at all !!!!
*
GEOSGeometry *g;
gaiaGeomCollPtr geoColl = gaiaAllocGeomColl();
gaiaInsertLinestringInGeomColl(geoColl, gaiaCloneLinestring(ln));
g = gaiaToGeos (geoColl);
ret = GEOSisClosed (g);
GEOSGeom_destroy (g);
gaiaFreeGeomColl(geoColl);
*/
/* so we'll use this internal default in order to circumvent the above issue */
double x1;
double y1;
double z1;
double m1;
double x2;
double y2;
double z2;
double m2;
gaiaLineGetPoint (ln, 0, &x1, &y1, &z1, &m1);
gaiaLineGetPoint (ln, ln->Points - 1, &x2, &y2, &z2, &m2);
if (x1 == x2 && y1 == y2 && z1 == z2)
ret = 1;
else
ret = 0;
if (ret == 0)
{
/* this line isn't closed, so we don't need to continue */
break;
}
ln = ln->Next;
}
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaIsClosedGeom (gaiaGeomCollPtr geom)
{
gaiaResetGeosMsg ();
return gaiaIsClosedGeom_r (NULL, geom);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplify (gaiaGeomCollPtr geom, double tolerance)
{
/* builds a simplified geometry using the Douglas-Peuker algorihtm */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSSimplify (g1, tolerance);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || tolerance == 0.0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplify_r (const void *p_cache, gaiaGeomCollPtr geom,
double tolerance)
{
/* builds a simplified geometry using the Douglas-Peuker algorihtm */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSSimplify_r (handle, g1, tolerance);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplifyPreserveTopology (gaiaGeomCollPtr geom, double tolerance)
{
/* builds a simplified geometry using the Douglas-Peuker algorihtm [preserving topology] */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSTopologyPreserveSimplify (g1, tolerance);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || tolerance == 0.0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollSimplifyPreserveTopology_r (const void *p_cache,
gaiaGeomCollPtr geom, double tolerance)
{
/* builds a simplified geometry using the Douglas-Peuker algorihtm [preserving topology] */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSTopologyPreserveSimplify_r (handle, g1, tolerance);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConvexHull (gaiaGeomCollPtr geom)
{
/* builds a geometry that is the convex hull of GEOM */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSConvexHull (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConvexHull_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* builds a geometry that is the convex hull of GEOM */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSConvexHull_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollBuffer (gaiaGeomCollPtr geom, double radius, int points)
{
/* builds a geometry that is the GIS buffer of GEOM */
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSBufferParams *params = NULL;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
/* setting up Buffer params */
params = GEOSBufferParams_create ();
GEOSBufferParams_setEndCapStyle (params, GEOSBUF_CAP_ROUND);
GEOSBufferParams_setJoinStyle (params, GEOSBUF_JOIN_ROUND);
GEOSBufferParams_setMitreLimit (params, 5.0);
GEOSBufferParams_setQuadrantSegments (params, points);
GEOSBufferParams_setSingleSided (params, 0);
g2 = GEOSBufferWithParams (g1, params, radius);
GEOSGeom_destroy (g1);
GEOSBufferParams_destroy (params);
if (!g2)
return NULL;
if (GEOSisEmpty (g2) == 1)
{
GEOSGeom_destroy (g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || radius == 0.0 || points == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeomCollBuffer_r (const void *p_cache, gaiaGeomCollPtr geom, double radius,
int points)
{
/* builds a geometry that is the GIS buffer of GEOM */
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSBufferParams *params = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
int quadsegs = 30;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
/* setting up Buffer params */
params = GEOSBufferParams_create_r (handle);
GEOSBufferParams_setEndCapStyle_r (handle, params,
cache->buffer_end_cap_style);
GEOSBufferParams_setJoinStyle_r (handle, params, cache->buffer_join_style);
GEOSBufferParams_setMitreLimit_r (handle, params,
cache->buffer_mitre_limit);
if (points > 0)
quadsegs = points;
else if (cache->buffer_quadrant_segments > 0)
quadsegs = cache->buffer_quadrant_segments;
GEOSBufferParams_setQuadrantSegments_r (handle, params, quadsegs);
GEOSBufferParams_setSingleSided_r (handle, params, 0);
g2 = GEOSBufferWithParams_r (handle, g1, params, radius);
GEOSGeom_destroy_r (handle, g1);
GEOSBufferParams_destroy_r (handle, params);
if (!g2)
return NULL;
if (GEOSisEmpty_r (handle, g2) == 1)
{
GEOSGeom_destroy_r (handle, g2);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
static void
auxFromGeosPolygon (GEOSContextHandle_t handle, const GEOSGeometry * geos,
gaiaGeomCollPtr result)
{
/* converting a Polygon from GEOS to SpatiaLite */
const GEOSGeometry *geos_ring;
const GEOSCoordSequence *coords;
unsigned int pts;
unsigned int geos_dims;
int interiors;
int iv;
int ib;
double x;
double y;
double z;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return;
#endif
if (handle != NULL)
{
geos_ring = GEOSGetExteriorRing_r (handle, geos);
interiors = GEOSGetNumInteriorRings_r (handle, geos);
coords = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getDimensions_r (handle, coords, &geos_dims);
GEOSCoordSeq_getSize_r (handle, coords, &pts);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_ring = GEOSGetExteriorRing (geos);
interiors = GEOSGetNumInteriorRings (geos);
coords = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (coords, &geos_dims);
GEOSCoordSeq_getSize (coords, &pts);
#endif
}
pg = gaiaAddPolygonToGeomColl (result, pts, interiors);
/* setting up the Exterior ring */
rng = pg->Exterior;
for (iv = 0; iv < (int) pts; iv++)
{
if (geos_dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, coords, iv, &x);
GEOSCoordSeq_getY_r (handle, coords, iv, &y);
GEOSCoordSeq_getZ_r (handle, coords, iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (coords, iv, &x);
GEOSCoordSeq_getY (coords, iv, &y);
GEOSCoordSeq_getZ (coords, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, coords, iv, &x);
GEOSCoordSeq_getY_r (handle, coords, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (coords, iv, &x);
GEOSCoordSeq_getY (coords, iv, &y);
#endif
}
z = 0.0;
}
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
for (ib = 0; ib < interiors; ib++)
{
/* setting up any interior ring */
if (handle != NULL)
{
geos_ring = GEOSGetInteriorRingN_r (handle, geos, ib);
coords = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getDimensions_r (handle, coords, &geos_dims);
GEOSCoordSeq_getSize_r (handle, coords, &pts);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_ring = GEOSGetInteriorRingN (geos, ib);
coords = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getDimensions (coords, &geos_dims);
GEOSCoordSeq_getSize (coords, &pts);
#endif
}
rng = gaiaAddInteriorRing (pg, ib, pts);
for (iv = 0; iv < (int) pts; iv++)
{
if (geos_dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, coords, iv, &x);
GEOSCoordSeq_getY_r (handle, coords, iv, &y);
GEOSCoordSeq_getZ_r (handle, coords, iv, &z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (coords, iv, &x);
GEOSCoordSeq_getY (coords, iv, &y);
GEOSCoordSeq_getZ (coords, iv, &z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, coords, iv, &x);
GEOSCoordSeq_getY_r (handle, coords, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (coords, iv, &x);
GEOSCoordSeq_getY (coords, iv, &y);
#endif
}
z = 0.0;
}
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
}
static void
auxGeosMbr (GEOSContextHandle_t handle, const GEOSCoordSequence * cs,
unsigned int pts, double *min_x, double *min_y, double *max_x,
double *max_y)
{
/* computing the MBR */
int iv;
double x;
double y;
*min_x = DBL_MAX;
*min_y = DBL_MAX;
*max_x = 0 - DBL_MAX;
*max_y = 0 - DBL_MAX;
for (iv = 0; iv < (int) pts; iv++)
{
if (handle != NULL)
{
GEOSCoordSeq_getX_r (handle, cs, iv, &x);
GEOSCoordSeq_getY_r (handle, cs, iv, &y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_getX (cs, iv, &x);
GEOSCoordSeq_getY (cs, iv, &y);
#endif
}
if (x < *min_x)
*min_x = x;
if (x > *max_x)
*max_x = x;
if (y < *min_y)
*min_y = y;
if (y > *max_y)
*max_y = y;
}
}
static gaiaGeomCollPtr
gaiaPolygonizeCommon (const void *cache, GEOSContextHandle_t handle,
gaiaGeomCollPtr geom, int force_multi)
{
/* attempts to rearrange a generic Geometry into a (multi)polygon */
int ig;
int ib;
int iv;
int interiors;
int geos_dims = 2;
int pts = 0;
int lns = 0;
int pgs = 0;
int items;
int error = 0;
double x;
double y;
double z;
double m;
gaiaGeomCollPtr result = NULL;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSCoordSequence *cs;
const GEOSGeometry *const *geos_list = NULL;
GEOSGeometry **p_item;
GEOSGeometry *geos;
const GEOSGeometry *geos_item;
const GEOSGeometry *geos_item2;
const GEOSGeometry *geos_ring;
char *valid_polygons = NULL;
const GEOSCoordSequence *coords;
unsigned int pts1;
unsigned int pts2;
double min_x1;
double max_x1;
double min_y1;
double max_y1;
double min_x2;
double max_x2;
double min_y2;
double max_y2;
int ret;
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!geom)
return NULL;
if (cache != NULL)
ret = gaiaIsToxic_r (cache, geom);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
ret = gaiaIsToxic (geom);
#endif
if (ret)
return NULL;
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts || pgs)
return NULL;
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
if (!lns)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_Z_M)
geos_dims = 3;
/* allocating GEOS linestrings */
geos_list = malloc (sizeof (const GEOSGeometry * const *) * lns);
p_item = (GEOSGeometry **) geos_list;
for (iv = 0; iv < lns; iv++)
{
/* initializing to NULL */
*p_item++ = NULL;
}
p_item = (GEOSGeometry **) geos_list;
/* initializing GEOS linestrings */
ln = geom->FirstLinestring;
while (ln)
{
if (handle != NULL)
cs = GEOSCoordSeq_create_r (handle, ln->Points, geos_dims);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
cs = GEOSCoordSeq_create (ln->Points, geos_dims);
#endif
for (iv = 0; iv < ln->Points; iv++)
{
/* exterior ring segments */
z = 0.0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (geos_dims == 3)
{
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
GEOSCoordSeq_setZ_r (handle, cs, iv, z);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
GEOSCoordSeq_setZ (cs, iv, z);
#endif
}
}
else
{
if (handle != NULL)
{
GEOSCoordSeq_setX_r (handle, cs, iv, x);
GEOSCoordSeq_setY_r (handle, cs, iv, y);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSCoordSeq_setX (cs, iv, x);
GEOSCoordSeq_setY (cs, iv, y);
#endif
}
}
}
if (handle != NULL)
*p_item++ = GEOSGeom_createLineString_r (handle, cs);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
*p_item++ = GEOSGeom_createLineString (cs);
#endif
ln = ln->Next;
}
/* calling GEOSPolygonize */
if (handle != NULL)
geos = GEOSPolygonize_r (handle, geos_list, lns);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos = GEOSPolygonize (geos_list, lns);
#endif
if (geos == NULL)
goto cleanup;
/*
/
/ GEOSPolygonize is expected to return a collection of Polygons
/
/ CAVEAT: internal holes are returned as such (interior rings in
/ some Polygon), but are returned as distinct Polygons too
/
/ we must check this, so to *not* return Polygons representing holes
/
*/
error = 0;
if (handle != NULL)
items = GEOSGetNumGeometries_r (handle, geos);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
items = GEOSGetNumGeometries (geos);
#endif
for (ig = 0; ig < items; ig++)
{
/* looping on elementaty GEOS geometries */
if (handle != NULL)
{
geos_item = GEOSGetGeometryN_r (handle, geos, ig);
if (GEOSGeomTypeId_r (handle, geos_item) != GEOS_POLYGON)
{
/* not a Polygon ... ouch ... */
error = 1;
goto cleanup;
}
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_item = GEOSGetGeometryN (geos, ig);
if (GEOSGeomTypeId (geos_item) != GEOS_POLYGON)
{
/* not a Polygon ... ouch ... */
error = 1;
goto cleanup;
}
#endif
}
}
/* identifying valid Polygons [excluding holes] */
valid_polygons = malloc (sizeof (char *) * items);
for (ig = 0; ig < items; ig++)
valid_polygons[ig] = 'Y';
for (ig = 0; ig < items; ig++)
{
/* looping on elementaty GEOS Polygons */
if (handle != NULL)
{
geos_item = GEOSGetGeometryN_r (handle, geos, ig);
interiors = GEOSGetNumInteriorRings_r (handle, geos_item);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_item = GEOSGetGeometryN (geos, ig);
interiors = GEOSGetNumInteriorRings (geos_item);
#endif
}
for (ib = 0; ib < interiors; ib++)
{
/* looping on any interior ring */
if (handle != NULL)
{
geos_ring =
GEOSGetInteriorRingN_r (handle, geos_item, ib);
coords = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getSize_r (handle, coords, &pts1);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_ring = GEOSGetInteriorRingN (geos_item, ib);
coords = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getSize (coords, &pts1);
#endif
}
auxGeosMbr (handle, coords, pts1, &min_x1, &min_y1, &max_x1,
&max_y1);
for (iv = 0; iv < items; iv++)
{
if (iv == ig)
{
/* skipping the Polygon itself */
continue;
}
if (valid_polygons[iv] == 'N')
{
/* skipping any already invalid Polygon */
continue;
}
if (handle != NULL)
{
geos_item2 = GEOSGetGeometryN_r (handle, geos, iv);
if (GEOSGetNumInteriorRings_r (handle, geos_item2) >
0)
{
/* this Polygon contains holes [surely valid] */
continue;
}
geos_ring =
GEOSGetExteriorRing_r (handle, geos_item2);
coords = GEOSGeom_getCoordSeq_r (handle, geos_ring);
GEOSCoordSeq_getSize_r (handle, coords, &pts2);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
geos_item2 = GEOSGetGeometryN (geos, iv);
if (GEOSGetNumInteriorRings (geos_item2) > 0)
{
/* this Polygon contains holes [surely valid] */
continue;
}
geos_ring = GEOSGetExteriorRing (geos_item2);
coords = GEOSGeom_getCoordSeq (geos_ring);
GEOSCoordSeq_getSize (coords, &pts2);
#endif
}
if (pts1 == pts2)
{
auxGeosMbr (handle, coords, pts2, &min_x2, &min_y2,
&max_x2, &max_y2);
if (min_x1 == min_x2 && min_y1 == min_y2
&& max_x1 == max_x2 && max_y1 == max_y2)
{
/* same #points, same MBRs: invalidating */
valid_polygons[iv] = 'N';
}
}
}
}
}
/* creating the Geometry to be returned */
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
if (force_multi)
result->DeclaredType = GAIA_MULTIPOLYGON;
for (ig = 0; ig < items; ig++)
{
/* looping on GEOS Polygons */
if (handle != NULL)
geos_item = GEOSGetGeometryN_r (handle, geos, ig);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
geos_item = GEOSGetGeometryN (geos, ig);
#endif
if (valid_polygons[ig] == 'Y')
auxFromGeosPolygon (handle, geos_item, result);
}
cleanup:
if (valid_polygons != NULL)
free (valid_polygons);
if (geos_list != NULL)
{
/* memory cleanup */
p_item = (GEOSGeometry **) geos_list;
for (iv = 0; iv < lns; iv++)
{
if (*p_item != NULL)
{
if (handle != NULL)
GEOSGeom_destroy_r (handle, *p_item);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
GEOSGeom_destroy (*p_item);
#endif
}
p_item++;
}
p_item = (GEOSGeometry **) geos_list;
free (p_item);
}
if (geos != NULL)
{
if (handle != NULL)
GEOSGeom_destroy_r (handle, geos);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
GEOSGeom_destroy (geos);
#endif
}
if (error || result->FirstPolygon == NULL)
{
gaiaFreeGeomColl (result);
return NULL;
}
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaPolygonize (gaiaGeomCollPtr geom, int force_multi)
{
/* attempts to rearrange a generic Geometry into a (multi)polygon */
gaiaResetGeosMsg ();
return gaiaPolygonizeCommon (NULL, NULL, geom, force_multi);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaPolygonize_r (const void *p_cache, gaiaGeomCollPtr geom, int force_multi)
{
/* attempts to rearrange a generic Geometry into a (multi)polygon */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
return gaiaPolygonizeCommon (cache, handle, geom, force_multi);
}
GAIAGEO_DECLARE int
gaiaGeomCollCovers (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if geom1 "spatially covers" geom2 */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSCovers (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret == 2)
return -1;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollCovers_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if geom1 "spatially covers" geom2 */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCovers_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedCovers (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if geom1 "spatially covers" geom2 */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr geom;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_contains (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
if (geom == geom2)
ret = GEOSPreparedCovers_r (handle, gPrep, g2);
else
ret = GEOSPreparedCoveredBy_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCovers_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollCoveredBy (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* checks if geom1 is "spatially covered by" geom2 */
int ret = -1;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSCoveredBy (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret == 2)
return -1;
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollCoveredBy_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/* checks if geom1 is "spatially covered by" geom2 */
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCoveredBy_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
GAIAGEO_DECLARE int
gaiaGeomCollPreparedCoveredBy (const void *p_cache, gaiaGeomCollPtr geom1,
unsigned char *blob1, int size1,
gaiaGeomCollPtr geom2, unsigned char *blob2,
int size2)
{
/* checks if geom1 is "spatially covered by" geom2 */
int ret;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSPreparedGeometry *gPrep;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSContextHandle_t handle = NULL;
gaiaGeomCollPtr geom;
gaiaResetGeosMsg ();
if (cache == NULL)
return -1;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1;
/* quick check based on MBRs comparison */
if (!splite_mbr_within (geom1, geom2))
return 0;
/* handling the internal GEOS cache */
if (evalGeosCache
(cache, geom1, blob1, size1, geom2, blob2, size2, &gPrep, &geom))
{
g2 = gaiaToGeos_r (cache, geom);
if (geom == geom2)
ret = GEOSPreparedCoveredBy_r (handle, gPrep, g2);
else
ret = GEOSPreparedCovers_r (handle, gPrep, g2);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSCoveredBy_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret == 2)
return -1;
return ret;
}
#endif /* end including GEOS */
libspatialite-5.1.0/src/gaiageo/gg_relations_ext.c 0000644 0001750 0001750 00000501324 14463127014 017157 0000000 0000000 /*
gg_relations_ext.c -- Gaia spatial relations [advanced]
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#ifndef OMIT_GEOS /* including GEOS */
#ifdef GEOS_REENTRANT
#ifdef GEOS_ONLY_REENTRANT
#define GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
#endif
#endif
#include
#endif
#include
#include
#include
#ifndef OMIT_GEOS /* including GEOS */
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaOffsetCurve (gaiaGeomCollPtr geom, double radius, int points,
int left_right)
{
/*
// builds a geometry that is the OffsetCurve of GEOM
// (which is expected to be of the LINESTRING type)
//
*/
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
int closed = 0;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (left_right < 0)
left_right = 0; /* silencing stupid compiler warnings */
/* checking the input geometry for validity */
pt = geom->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
if (gaiaIsClosed (ln))
closed++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* counting how many POLYGON are there */
pgs++;
pg = pg->Next;
}
if (pts > 0 || pgs > 0 || lns > 1 || closed > 0)
return NULL;
/* all right: this one simply is a LINESTRING */
geom->DeclaredType = GAIA_LINESTRING;
g1 = gaiaToGeos (geom);
g2 = GEOSOffsetCurve (g1, radius, points, GEOSBUF_JOIN_ROUND, 5.0);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || radius == 0.0 || points == 0 || left_right == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaOffsetCurve_r (const void *p_cache, gaiaGeomCollPtr geom, double radius,
int points, int left_right)
{
/*
// builds a geometry that is the OffsetCurve of GEOM
// (which is expected to be of the LINESTRING type)
//
*/
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
int closed = 0;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (left_right < 0)
left_right = 0; /* silencing stupid compiler warnings */
/* checking the input geometry for validity */
pt = geom->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
if (gaiaIsClosed (ln))
closed++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* counting how many POLYGON are there */
pgs++;
pg = pg->Next;
}
if (pts > 0 || pgs > 0 || lns > 1 || closed > 0)
return NULL;
/* all right: this one simply is a LINESTRING */
geom->DeclaredType = GAIA_LINESTRING;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSOffsetCurve_r (handle, g1, radius, points,
GEOSBUF_JOIN_ROUND, 5.0);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSingleSidedBuffer (gaiaGeomCollPtr geom, double radius, int points,
int left_right)
{
/*
// builds a geometry that is the SingleSided BUFFER of GEOM
// (which is expected to be of the LINESTRING type)
//
*/
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSBufferParams *params = NULL;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
int closed = 0;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
/* checking the input geometry for validity */
pt = geom->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
if (gaiaIsClosed (ln))
closed++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* counting how many POLYGON are there */
pgs++;
pg = pg->Next;
}
if (pts > 0 || pgs > 0 || lns > 1 || closed > 0)
return NULL;
/* all right: this one simply is a LINESTRING */
geom->DeclaredType = GAIA_LINESTRING;
g1 = gaiaToGeos (geom);
/* setting up Buffer params */
params = GEOSBufferParams_create ();
GEOSBufferParams_setEndCapStyle (params, GEOSBUF_CAP_ROUND);
GEOSBufferParams_setJoinStyle (params, GEOSBUF_JOIN_ROUND);
GEOSBufferParams_setMitreLimit (params, 5.0);
GEOSBufferParams_setQuadrantSegments (params, points);
GEOSBufferParams_setSingleSided (params, 1);
/* creating the SingleSided Buffer */
if (left_right == 0)
{
/* right-sided requires NEGATIVE radius */
radius *= -1.0;
}
g2 = GEOSBufferWithParams (g1, params, radius);
GEOSGeom_destroy (g1);
GEOSBufferParams_destroy (params);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || radius == 0.0 || points == 0 || left_right == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSingleSidedBuffer_r (const void *p_cache, gaiaGeomCollPtr geom,
double radius, int points, int left_right)
{
/*
// builds a geometry that is the SingleSided BUFFER of GEOM
// (which is expected to be of the LINESTRING type)
//
*/
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSBufferParams *params = NULL;
int quadsegs = 30;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
int closed = 0;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
/* checking the input geometry for validity */
pt = geom->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
if (gaiaIsClosed (ln))
closed++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* counting how many POLYGON are there */
pgs++;
pg = pg->Next;
}
if (pts > 0 || pgs > 0 || lns > 1 || closed > 0)
return NULL;
/* all right: this one simply is a LINESTRING */
geom->DeclaredType = GAIA_LINESTRING;
g1 = gaiaToGeos_r (cache, geom);
/* setting up Buffer params */
params = GEOSBufferParams_create_r (handle);
GEOSBufferParams_setEndCapStyle_r (handle, params,
cache->buffer_end_cap_style);
GEOSBufferParams_setJoinStyle_r (handle, params, cache->buffer_join_style);
GEOSBufferParams_setMitreLimit_r (handle, params,
cache->buffer_mitre_limit);
if (points > 0)
quadsegs = points;
else if (cache->buffer_quadrant_segments > 0)
quadsegs = cache->buffer_quadrant_segments;
GEOSBufferParams_setQuadrantSegments_r (handle, params, quadsegs);
GEOSBufferParams_setSingleSided_r (handle, params, 1);
/* creating the SingleSided Buffer */
if (left_right == 0)
{
/* right-sided requires NEGATIVE radius */
radius *= -1.0;
}
g2 = GEOSBufferWithParams_r (handle, g1, params, radius);
GEOSGeom_destroy_r (handle, g1);
GEOSBufferParams_destroy_r (handle, params);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE int
gaiaHausdorffDistance (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double *xdist)
{
/*
/ computes the (discrete) Hausdorff distance intercurring
/ between GEOM-1 and GEOM-2
*/
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double dist;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSHausdorffDistance (g1, g2, &dist);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret)
*xdist = dist;
#else
if (geom1 == NULL || geom2 == NULL || xdist == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaHausdorffDistance_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *xdist)
{
/*
/ computes the (discrete) Hausdorff distance intercurring
/ between GEOM-1 and GEOM-2
*/
double dist;
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSHausdorffDistance_r (handle, g1, g2, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
#ifdef GEOS_370 /* only if GEOS_370 support is available */
GAIAGEO_DECLARE int
gaiaHausdorffDistanceDensify (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double densify_fract, double *xdist)
{
/*
/ computes the (discrete) Hausdorff distance intercurring
/ between GEOM-1 and GEOM-2
*/
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double dist;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSHausdorffDistanceDensify (g1, g2, densify_fract, &dist);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret)
*xdist = dist;
#else
if (geom1 == NULL || geom2 == NULL || xdist == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaHausdorffDistanceDensify_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double densify_fract,
double *xdist)
{
/*
/ computes the (discrete) Hausdorff distance intercurring
/ between GEOM-1 and GEOM-2
*/
double dist;
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSHausdorffDistanceDensify_r (handle, g1, g2, densify_fract, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
GAIAGEO_DECLARE int
gaiaFrechetDistance (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double *xdist)
{
/*
/ computes the (discrete) Frechet distance intercurring
/ between GEOM-1 and GEOM-2
*/
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double dist;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSFrechetDistance (g1, g2, &dist);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret)
*xdist = dist;
#else
if (geom1 == NULL || geom2 == NULL || xdist == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaFrechetDistance_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *xdist)
{
/*
/ computes the (discrete) Frechet distance intercurring
/ between GEOM-1 and GEOM-2
*/
double dist;
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSFrechetDistance_r (handle, g1, g2, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
GAIAGEO_DECLARE int
gaiaFrechetDistanceDensify (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double densify_fract, double *xdist)
{
/*
/ computes the (discrete) Frechet distance intercurring
/ between GEOM-1 and GEOM-2
*/
int ret = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
double dist;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
ret = GEOSFrechetDistanceDensify (g1, g2, densify_fract, &dist);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (ret)
*xdist = dist;
#else
if (geom1 == NULL || geom2 == NULL || xdist == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return ret;
}
GAIAGEO_DECLARE int
gaiaFrechetDistanceDensify_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double densify_fract,
double *xdist)
{
/*
/ computes the (discrete) Frechet distance intercurring
/ between GEOM-1 and GEOM-2
*/
double dist;
int ret;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
ret = GEOSFrechetDistanceDensify_r (handle, g1, g2, densify_fract, &dist);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (ret)
*xdist = dist;
return ret;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumRotatedRectangle (gaiaGeomCollPtr geom)
{
/*
/ Calculates the minimum rotated rectangular POLYGON which encloses
/ the input geometry
/
/ The rectangle has width equal to the minimum diameter, and a longer length.
/ If the convex hull of the input is degenerate (a line or point) a LINESTRING
/ or POINT is returned.
/ The minimum rotated rectangle can be used as an extremely generalized
/ representation for the given geometry.
*/
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSMinimumRotatedRectangle (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL || tolerance == 0.0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumRotatedRectangle_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/*
/ Calculates the minimum rotated rectangular POLYGON which encloses
/ the input geometry
/
/ The rectangle has width equal to the minimum diameter, and a longer length.
/ If the convex hull of the input is degenerate (a line or point) a LINESTRING
/ or POINT is returned.
/ The minimum rotated rectangle can be used as an extremely generalized
/ representation for the given geometry.
*/
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSMinimumRotatedRectangle_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumBoundingCircle (gaiaGeomCollPtr geom, double *xradius,
gaiaGeomCollPtr * xcenter)
{
/*
/ Returns the Minimum Bounding Circle for a generic geometry,
/ * xradius will point to the Radius vaiue of the circle
/ * xcenter will point to the POINT Geometry corresponding to the center
/ of the circle
*/
gaiaGeomCollPtr geo = NULL;
gaiaGeomCollPtr center = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
double radius;
gaiaResetGeosMsg ();
if (xradius != NULL)
*xradius = 0.0;
if (xcenter != NULL)
*xcenter = NULL;
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSMinimumBoundingCircle (g1, &radius, &g3);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (!g3)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
center = gaiaFromGeos_XYZ (g3);
else if (geom->DimensionModel == GAIA_XY_M)
center = gaiaFromGeos_XYM (g3);
else if (geom->DimensionModel == GAIA_XY_Z_M)
center = gaiaFromGeos_XYZM (g3);
else
center = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL || center == NULL)
{
if (geo != NULL)
gaiaFreeGeomColl (geo);
if (center != NULL)
gaiaFreeGeomColl (center);
return NULL;
}
geo->Srid = geom->Srid;
if (xradius != NULL)
*xradius = radius;
if (xcenter != NULL)
*xcenter = center;
else
gaiaFreeGeomColl (center);
#else
if (geom == NULL || center == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumBoundingCircle_r (const void *p_cache, gaiaGeomCollPtr geom,
double *xradius, gaiaGeomCollPtr * xcenter)
{
/*
/ Returns the Minimum Bounding Circle for a generic geometry,
/ * xradius will point to the Radius vaiue of the circle
/ * xcenter will point to the POINT Geometry corresponding to the center
/ of the circle
*/
gaiaGeomCollPtr geo;
gaiaGeomCollPtr center;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
double radius;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (xradius != NULL)
*xradius = 0.0;
if (xcenter != NULL)
*xcenter = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSMinimumBoundingCircle_r (handle, g1, &radius, &g3);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (!g3)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
center = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom->DimensionModel == GAIA_XY_M)
center = gaiaFromGeos_XYM_r (cache, g3);
else if (geom->DimensionModel == GAIA_XY_Z_M)
center = gaiaFromGeos_XYZM_r (cache, g3);
else
center = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL || center == NULL)
{
if (geo != NULL)
gaiaFreeGeomColl (geo);
if (center != NULL)
gaiaFreeGeomColl (center);
return NULL;
}
geo->Srid = geom->Srid;
if (xradius != NULL)
*xradius = radius;
if (xcenter != NULL)
*xcenter = center;
else
gaiaFreeGeomColl (center);
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumWidth (gaiaGeomCollPtr geom)
{
/*
/ Returns a LINESTRING geometry which represents the minimum diameter of the geometry.
/
/ The minimum diameter is defined to be the width of the smallest band that
/ contains the geometry, where a band is a strip of the plane defined
/ by two parallel lines. This can be thought of as the smallest hole that the geometry
/ can be moved through, with a single rotation.
*/
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSMinimumWidth (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumWidth_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/*
/ Returns a LINESTRING geometry which represents the minimum diameter of the geometry.
/
/ The minimum diameter is defined to be the width of the smallest band that
/ contains the geometry, where a band is a strip of the plane defined
/ by two parallel lines. This can be thought of as the smallest hole that the geometry
/ can be moved through, with a single rotation.
*/
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSMinimumWidth_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
GAIAGEO_DECLARE int
gaiaMinimumClearance (gaiaGeomCollPtr geom, double *clearance)
{
/*
/ Computes the minimum clearance of a geometry. The minimum clearance is the smallest amount by which
/ a vertex could be move to produce an invalid polygon, a non-simple linestring, or a multipoint with
/ repeated points. If a geometry has a minimum clearance of 'eps', it can be said that:
/
/ - No two distinct vertices in the geometry are separated by less than 'eps'
/ - No vertex is closer than 'eps' to a line segment of which it is not an endpoint.
/
/ If the minimum clearance cannot be defined for a geometry (such as with a single point, or a multipoint
/ whose points are identical, a value of Infinity will be calculated.
*/
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
int ret;
double result;
gaiaResetGeosMsg ();
if (!geom)
return 0;
g1 = gaiaToGeos (geom);
ret = GEOSMinimumClearance (g1, &result);
GEOSGeom_destroy (g1);
if (ret != 0)
return 0;
*clearance = result;
return 1;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return 0;
}
GAIAGEO_DECLARE int
gaiaMinimumClearance_r (const void *p_cache, gaiaGeomCollPtr geom,
double *clearance)
{
/*
/ Computes the minimum clearance of a geometry. The minimum clearance is the smallest amount by which
/ a vertex could be move to produce an invalid polygon, a non-simple linestring, or a multipoint with
/ repeated points. If a geometry has a minimum clearance of 'eps', it can be said that:
/
/ - No two distinct vertices in the geometry are separated by less than 'eps'
/ - No vertex is closer than 'eps' to a line segment of which it is not an endpoint.
/
/ If the minimum clearance cannot be defined for a geometry (such as with a single point, or a multipoint
/ whose points are identical, a value of Infinity will be calculated..
*/
GEOSGeometry *g1;
int ret;
double result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom)
return 0;
g1 = gaiaToGeos_r (cache, geom);
ret = GEOSMinimumClearance_r (handle, g1, &result);
GEOSGeom_destroy_r (handle, g1);
if (ret != 0)
return 0;
*clearance = result;
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumClearanceLine (gaiaGeomCollPtr geom)
{
/*
/ Returns a LineString whose endpoints define the minimum clearance of a geometry.
/
/ If the geometry has no minimum clearance (as e.g. a POINT), NULL will be returned.
*/
gaiaGeomCollPtr geo = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSMinimumClearanceLine (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g2);
else
geo = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMinimumClearanceLine_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/*
/ Returns a LineString whose endpoints define the minimum clearance of a geometry.
/
/ If the geometry has no minimum clearance (as e.g. a POINT), NULL will be returned.
*/
gaiaGeomCollPtr geo;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSMinimumClearanceLine_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g2);
else
geo = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (geo == NULL)
return NULL;
geo->Srid = geom->Srid;
return geo;
}
#endif /* end GEOS_370 conditional */
#ifdef GEOS_3100 /* only if GEOS_3100 support is available */
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosDensify (gaiaGeomCollPtr geom, double tolerance)
{
/* return a densified geometry using a given distance tolerance. */
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *in;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (tolerance <= 0.0)
return NULL;
in = gaiaToGeos (geom);
out = GEOSDensify (in, tolerance);
GEOSGeom_destroy (in);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (out);
else
result = gaiaFromGeos_XY (out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosDensify_r (const void *p_cache, gaiaGeomCollPtr geom, double tolerance)
{
/* return a densified geometry using a given distance tolerance. */
GEOSGeometry *in;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (tolerance <= 0.0)
return NULL;
in = gaiaToGeos_r (cache, geom);
out = GEOSDensify_r (handle, in, tolerance);
GEOSGeom_destroy_r (handle, in);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, out);
else
result = gaiaFromGeos_XY_r (cache, out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConstrainedDelaunayTriangulation (gaiaGeomCollPtr geom)
{
/* Constrained Delaunay Triangulation */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSConstrainedDelaunayTriangulation (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConstrainedDelaunayTriangulation_r (const void *p_cache,
gaiaGeomCollPtr geom)
{
/* Constrained Delaunay Triangulation */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSConstrainedDelaunayTriangulation_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosMakeValid (gaiaGeomCollPtr geom, int keep_collapsed)
{
/*
/ Attempts to make an invalid geometry valid
/ GEOS method: STRUCTURE
*/
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSMakeValidParams *params;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
params = GEOSMakeValidParams_create ();
GEOSMakeValidParams_setMethod (params, GEOS_MAKE_VALID_STRUCTURE);
GEOSMakeValidParams_setKeepCollapsed (params, keep_collapsed);
g2 = GEOSMakeValidWithParams (g1, params);
GEOSMakeValidParams_destroy (params);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosMakeValid_r (const void *p_cache,
gaiaGeomCollPtr geom, int keep_collapsed)
{
/*
/ Attempts to make an invalid geometry valid
/ GEOS method: STRUCTURE
*/
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSMakeValidParams *params;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
params = GEOSMakeValidParams_create_r (handle);
GEOSMakeValidParams_setMethod_r (handle, params, GEOS_MAKE_VALID_STRUCTURE);
GEOSMakeValidParams_setKeepCollapsed_r (handle, params, keep_collapsed);
g2 = GEOSMakeValidWithParams_r (handle, g1, params);
GEOSMakeValidParams_destroy_r (handle, params);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMaximumInscribedCircle (gaiaGeomCollPtr geom, double tolerance)
{
/*
/ Constructs the Maximum Inscribed Circle for a polygonal geometry,
/ up to a specified tolerance.
/ The Maximum Inscribed Circle is determined by a point in the interior
/ of the area which has the farthest distance from the area boundary,
/ along with a boundary point at that distance.
/ In the context of geography the center of the Maximum Inscribed Circle
/ is known as the Pole of Inaccessibility.
/ A cartographic use case is to determine a suitable point to place a
/ map label within a polygon.
/ The radius length of the Maximum Inscribed Circle is a measure of
/ how "narrow" a polygon is.
/ It is the distance at which the negative buffer becomes empty.
/ The class supports polygons with holes and multipolygons.
/ The implementation uses a successive-approximation technique over a
/ grid of square cells covering the area geometry.
/ The grid is refined using a branch-and-bound algorithm.
/ Point containment and distance are computed in a performant way by
/ using spatial indexes.
/ Returns a two-point linestring, with one point at the center of the
/ inscribed circle and the other on the boundary of the inscribed circle.
*/
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *in;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
in = gaiaToGeos (geom);
out = GEOSMaximumInscribedCircle (in, tolerance);
GEOSGeom_destroy (in);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (out);
else
result = gaiaFromGeos_XY (out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL || tolerance == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMaximumInscribedCircle_r (const void *p_cache, gaiaGeomCollPtr geom,
double tolerance)
{
/*
/ Constructs the Maximum Inscribed Circle for a polygonal geometry,
/ up to a specified tolerance.
/ The Maximum Inscribed Circle is determined by a point in the interior
/ of the area which has the farthest distance from the area boundary,
/ along with a boundary point at that distance.
/ In the context of geography the center of the Maximum Inscribed Circle
/ is known as the Pole of Inaccessibility.
/ A cartographic use case is to determine a suitable point to place a
/ map label within a polygon.
/ The radius length of the Maximum Inscribed Circle is a measure of
/ how "narrow" a polygon is.
/ It is the distance at which the negative buffer becomes empty.
/ The class supports polygons with holes and multipolygons.
/ The implementation uses a successive-approximation technique over a
/ grid of square cells covering the area geometry.
/ The grid is refined using a branch-and-bound algorithm.
/ Point containment and distance are computed in a performant way by
/ using spatial indexes.
/ Returns a two-point linestring, with one point at the center of the
/ inscribed circle and the other on the boundary of the inscribed circle.
*/
GEOSGeometry *in;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
in = gaiaToGeos_r (cache, geom);
out = GEOSMaximumInscribedCircle_r (handle, in, tolerance);
GEOSGeom_destroy (in);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, out);
else
result = gaiaFromGeos_XY_r (cache, out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLargestEmptyCircle (gaiaGeomCollPtr geom, gaiaGeomCollPtr boundary,
double tolerance)
{
/*
/ Returns a LINESTRING geometry which represents the minimum diameter of the geometry.
/ The minimum diameter is defined to be the width of the smallest band that
/ contains the geometry, where a band is a strip of the plane defined
/ by two parallel lines. This can be thought of as the smallest hole that
/ the geometry can be moved through, with a single rotation.
*/
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *in;
GEOSGeometry *bdry;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
gaiaResetGeosMsg ();
if (!geom || !boundary)
return NULL;
in = gaiaToGeos (geom);
bdry = gaiaToGeos (boundary);
out = GEOSLargestEmptyCircle (in, bdry, tolerance);
GEOSGeom_destroy (in);
GEOSGeom_destroy (bdry);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (out);
else
result = gaiaFromGeos_XY (out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL || boundary == NULL || tolerance == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLargestEmptyCircle_r (const void *p_cache, gaiaGeomCollPtr geom,
gaiaGeomCollPtr boundary, double tolerance)
{
/*
/ Returns a LINESTRING geometry which represents the minimum diameter of the geometry.
/ The minimum diameter is defined to be the width of the smallest band that
/ contains the geometry, where a band is a strip of the plane defined
/ by two parallel lines. This can be thought of as the smallest hole that
/ the geometry can be moved through, with a single rotation.
*/
GEOSGeometry *in;
GEOSGeometry *bdry;
GEOSGeometry *out;
gaiaGeomCollPtr result = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom || !boundary)
return NULL;
in = gaiaToGeos_r (cache, geom);
bdry = gaiaToGeos_r (cache, boundary);
out = GEOSLargestEmptyCircle_r (handle, in, bdry, tolerance);
GEOSGeom_destroy (in);
GEOSGeom_destroy (bdry);
if (!out)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, out);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, out);
else
result = gaiaFromGeos_XY_r (cache, out);
GEOSGeom_destroy (out);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaReducePrecision (gaiaGeomCollPtr geom, double grid_size)
{
/*
/ Attempts to change the coordinate precision of a geometry.
*/
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSGeom_setPrecision (g1, grid_size, GEOS_PREC_VALID_OUTPUT);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaReducePrecision_r (const void *p_cache,
gaiaGeomCollPtr geom, double grid_size)
{
/*
/ Attempts to change the coordinate precision of a geometry.
*/
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSGeom_setPrecision_r (handle, g1, grid_size,
GEOS_PREC_VALID_OUTPUT);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
#endif /* end GEOS_3100 conditional */
#ifdef GEOS_3110 /* only if GEOS_3110 support is available */
GAIAGEO_DECLARE int
gaiaHilbertCode (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2, int level,
unsigned int *code)
{
/*
/ Calculate the Hilbert Code of the centroid of a Geometry
/ relative to an Extent
/ Level is the precision of the Hilbert Curve [1-16]
*/
int result = 0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1)
return 0;
if (!geom2)
return 0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
if (level < 1)
level = 1;
if (level > 16)
level = 16;
result = GEOSHilbertCode (g1, g2, level, code);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
return result;
#else
if (geom1 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
if (geom2 == NULL)
geom2 = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE int
gaiaHilbertCode_r (const void *p_cache,
gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2, int level,
unsigned int *code)
{
/*
/ Calculate the Hilbert Code of the centroid of a Geometry
/ relative to an Extent
/ Level is the precision of the Hilbert Curve [1-16]
*/
GEOSGeometry *g1;
GEOSGeometry *g2;
int result = 0;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
handle = cache->GEOS_handle;
if (handle == NULL)
return 0;
gaiaResetGeosMsg_r (cache);
if (!geom1)
return 0;
if (!geom2)
return 0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
if (level < 1)
level = 1;
if (level > 16)
level = 16;
result = GEOSHilbertCode_r (handle, g1, g2, level, code);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosConcaveHull (gaiaGeomCollPtr geom, double ratio, int allow_holes)
{
/* Concave Hull - the GEOS way */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (ratio < 0.0)
ratio = 0.0;
if (ratio > 1.0)
ratio = 1.0;
g1 = gaiaToGeos (geom);
g2 = GEOSConcaveHull (g1, ratio, allow_holes);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
#else
if (geom1 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaGeosConcaveHull_r (const void *p_cache, gaiaGeomCollPtr geom, double ratio,
int allow_holes)
{
/* Concave Hull - the GEOS way */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (ratio < 0.0)
ratio = 0.0;
if (ratio > 1.0)
ratio = 1.0;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSConcaveHull_r (handle, g1, ratio, allow_holes);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
#endif /* end GEOS_3110 conditional */
static gaiaGeomCollPtr
geom_as_lines (gaiaGeomCollPtr geom)
{
/* transforms a Geometry into a LINESTRING/MULTILINESTRING (if possible) */
gaiaGeomCollPtr result;
gaiaLinestringPtr ln;
gaiaLinestringPtr new_ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int iv;
int ib;
double x;
double y;
double z;
double m;
if (!geom)
return NULL;
if (geom->FirstPoint != NULL)
{
/* invalid: GEOM contains at least one POINT */
return NULL;
}
switch (geom->DimensionModel)
{
case GAIA_XY_Z_M:
result = gaiaAllocGeomCollXYZM ();
break;
case GAIA_XY_Z:
result = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
result = gaiaAllocGeomCollXYM ();
break;
default:
result = gaiaAllocGeomColl ();
break;
};
result->Srid = geom->Srid;
ln = geom->FirstLinestring;
while (ln)
{
/* copying any Linestring */
new_ln = gaiaAddLinestringToGeomColl (result, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* copying any Polygon Ring (as Linestring) */
rng = pg->Exterior;
new_ln = gaiaAddLinestringToGeomColl (result, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* exterior Ring */
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
new_ln = gaiaAddLinestringToGeomColl (result, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* any interior Ring */
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (new_ln->Coords, iv, x, y, m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaSetPoint (new_ln->Coords, iv, x, y);
}
}
}
pg = pg->Next;
}
return result;
}
static void
add_shared_linestring (gaiaGeomCollPtr geom, gaiaDynamicLinePtr dyn)
{
/* adding a LINESTRING from Dynamic Line */
int count = 0;
gaiaLinestringPtr ln;
gaiaPointPtr pt;
int iv;
if (!geom)
return;
if (!dyn)
return;
pt = dyn->First;
while (pt)
{
/* counting how many Points are there */
count++;
pt = pt->Next;
}
if (count == 0)
return;
ln = gaiaAddLinestringToGeomColl (geom, count);
iv = 0;
pt = dyn->First;
while (pt)
{
/* copying points into the LINESTRING */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, pt->X, pt->Y, pt->Z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, pt->X, pt->Y, pt->M);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, pt->X, pt->Y, pt->Z, pt->M);
}
else
{
gaiaSetPoint (ln->Coords, iv, pt->X, pt->Y);
}
iv++;
pt = pt->Next;
}
}
static void
append_shared_path (gaiaDynamicLinePtr dyn, gaiaLinestringPtr ln, int order)
{
/* appends a Shared Path item to Dynamic Line */
int iv;
double x;
double y;
double z;
double m;
if (order)
{
/* reversed order */
for (iv = ln->Points - 1; iv >= 0; iv--)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (x == dyn->Last->X && y == dyn->Last->Y
&& z == dyn->Last->Z)
;
else
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (x == dyn->Last->X && y == dyn->Last->Y
&& m == dyn->Last->M)
;
else
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
if (x == dyn->Last->X && y == dyn->Last->Y
&& z == dyn->Last->Z && m == dyn->Last->M)
;
else
gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (x == dyn->Last->X && y == dyn->Last->Y)
;
else
gaiaAppendPointToDynamicLine (dyn, x, y);
}
}
}
else
{
/* conformant order */
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (x == dyn->Last->X && y == dyn->Last->Y
&& z == dyn->Last->Z)
;
else
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (x == dyn->Last->X && y == dyn->Last->Y
&& m == dyn->Last->M)
;
else
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
if (x == dyn->Last->X && y == dyn->Last->Y
&& z == dyn->Last->Z && m == dyn->Last->M)
;
else
gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (x == dyn->Last->X && y == dyn->Last->Y)
;
else
gaiaAppendPointToDynamicLine (dyn, x, y);
}
}
}
}
static void
prepend_shared_path (gaiaDynamicLinePtr dyn, gaiaLinestringPtr ln, int order)
{
/* prepends a Shared Path item to Dynamic Line */
int iv;
double x;
double y;
double z;
double m;
if (order)
{
/* reversed order */
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (x == dyn->First->X && y == dyn->First->Y
&& z == dyn->First->Z)
;
else
gaiaPrependPointZToDynamicLine (dyn, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (x == dyn->First->X && y == dyn->First->Y
&& m == dyn->First->M)
;
else
gaiaPrependPointMToDynamicLine (dyn, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
if (x == dyn->First->X && y == dyn->First->Y
&& z == dyn->First->Z && m == dyn->First->M)
;
else
gaiaPrependPointZMToDynamicLine (dyn, x, y, z, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (x == dyn->First->X && y == dyn->First->Y)
;
else
gaiaPrependPointToDynamicLine (dyn, x, y);
}
}
}
else
{
/* conformant order */
for (iv = ln->Points - 1; iv >= 0; iv--)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
if (x == dyn->First->X && y == dyn->First->Y
&& z == dyn->First->Z)
;
else
gaiaPrependPointZToDynamicLine (dyn, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
if (x == dyn->First->X && y == dyn->First->Y
&& m == dyn->First->M)
;
else
gaiaPrependPointMToDynamicLine (dyn, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
if (x == dyn->First->X && y == dyn->First->Y
&& z == dyn->First->Z && m == dyn->First->M)
;
else
gaiaPrependPointZMToDynamicLine (dyn, x, y, z, m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
if (x == dyn->First->X && y == dyn->First->Y)
;
else
gaiaPrependPointToDynamicLine (dyn, x, y);
}
}
}
}
static gaiaGeomCollPtr
arrange_shared_paths (gaiaGeomCollPtr geom)
{
/* final aggregation step for shared paths */
gaiaLinestringPtr ln;
gaiaLinestringPtr *ln_array;
gaiaGeomCollPtr result;
gaiaDynamicLinePtr dyn;
int count;
int i;
int i2;
int iv;
double x;
double y;
double z;
double m;
int ok;
int ok2;
if (!geom)
return NULL;
count = 0;
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many Linestrings are there */
count++;
ln = ln->Next;
}
if (count == 0)
return NULL;
ln_array = malloc (sizeof (gaiaLinestringPtr) * count);
i = 0;
ln = geom->FirstLinestring;
while (ln)
{
/* populating the Linestring references array */
ln_array[i++] = ln;
ln = ln->Next;
}
/* allocating a new Geometry [MULTILINESTRING] */
switch (geom->DimensionModel)
{
case GAIA_XY_Z_M:
result = gaiaAllocGeomCollXYZM ();
break;
case GAIA_XY_Z:
result = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
result = gaiaAllocGeomCollXYM ();
break;
default:
result = gaiaAllocGeomColl ();
break;
};
result->Srid = geom->Srid;
result->DeclaredType = GAIA_MULTILINESTRING;
ok = 1;
while (ok)
{
/* looping until we have processed any input item */
ok = 0;
for (i = 0; i < count; i++)
{
if (ln_array[i] != NULL)
{
/* starting a new LINESTRING */
dyn = gaiaAllocDynamicLine ();
ln = ln_array[i];
ln_array[i] = NULL;
for (iv = 0; iv < ln->Points; iv++)
{
/* inserting the 'seed' path */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z,
&m);
gaiaAppendPointZMToDynamicLine (dyn, x, y, z,
m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
gaiaAppendPointToDynamicLine (dyn, x, y);
}
}
ok2 = 1;
while (ok2)
{
/* looping until we have checked any other item */
ok2 = 0;
for (i2 = 0; i2 < count; i2++)
{
/* expanding the 'seed' path */
if (ln_array[i2] == NULL)
continue;
ln = ln_array[i2];
/* checking the first vertex */
iv = 0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y,
&z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y,
&m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x,
&y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (x == dyn->Last->X && y == dyn->Last->Y)
{
/* appending this item to the 'seed' (conformant order) */
append_shared_path (dyn, ln, 0);
ln_array[i2] = NULL;
ok2 = 1;
continue;
}
if (x == dyn->First->X && y == dyn->First->Y)
{
/* prepending this item to the 'seed' (reversed order) */
prepend_shared_path (dyn, ln, 1);
ln_array[i2] = NULL;
ok2 = 1;
continue;
}
/* checking the last vertex */
iv = ln->Points - 1;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y,
&z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y,
&m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x,
&y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (x == dyn->Last->X && y == dyn->Last->Y)
{
/* appending this item to the 'seed' (reversed order) */
append_shared_path (dyn, ln, 1);
ln_array[i2] = NULL;
ok2 = 1;
continue;
}
if (x == dyn->First->X && y == dyn->First->Y)
{
/* prepending this item to the 'seed' (conformant order) */
prepend_shared_path (dyn, ln, 0);
ln_array[i2] = NULL;
ok2 = 1;
continue;
}
}
}
add_shared_linestring (result, dyn);
gaiaFreeDynamicLine (dyn);
ok = 1;
break;
}
}
}
free (ln_array);
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSharedPaths (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/*
// builds a geometry containing Shared Paths commons to GEOM1 & GEOM2
// (which are expected to be of the LINESTRING/MULTILINESTRING type)
//
*/
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
gaiaGeomCollPtr geo;
gaiaGeomCollPtr line1;
gaiaGeomCollPtr line2;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1)
return NULL;
if (!geom2)
return NULL;
/* transforming input geoms as Lines */
line1 = geom_as_lines (geom1);
line2 = geom_as_lines (geom2);
if (line1 == NULL || line2 == NULL)
{
if (line1)
gaiaFreeGeomColl (line1);
if (line2)
gaiaFreeGeomColl (line2);
return NULL;
}
g1 = gaiaToGeos (line1);
g2 = gaiaToGeos (line2);
gaiaFreeGeomColl (line1);
gaiaFreeGeomColl (line2);
g3 = GEOSSharedPaths (g1, g2);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (!g3)
return NULL;
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM (g3);
else
geo = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
result = arrange_shared_paths (geo);
gaiaFreeGeomColl (geo);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSharedPaths_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/*
// builds a geometry containing Shared Paths commons to GEOM1 & GEOM2
// (which are expected to be of the LINESTRING/MULTILINESTRING type)
//
*/
gaiaGeomCollPtr geo;
gaiaGeomCollPtr result;
gaiaGeomCollPtr line1;
gaiaGeomCollPtr line2;
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1)
return NULL;
if (!geom2)
return NULL;
/* transforming input geoms as Lines */
line1 = geom_as_lines (geom1);
line2 = geom_as_lines (geom2);
if (line1 == NULL || line2 == NULL)
{
if (line1)
gaiaFreeGeomColl (line1);
if (line2)
gaiaFreeGeomColl (line2);
return NULL;
}
g1 = gaiaToGeos_r (cache, line1);
g2 = gaiaToGeos_r (cache, line2);
gaiaFreeGeomColl (line1);
gaiaFreeGeomColl (line2);
g3 = GEOSSharedPaths_r (handle, g1, g2);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (!g3)
return NULL;
if (geom1->DimensionModel == GAIA_XY_Z)
geo = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
geo = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
geo = gaiaFromGeos_XYZM_r (cache, g3);
else
geo = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (geo == NULL)
return NULL;
geo->Srid = geom1->Srid;
result = arrange_shared_paths (geo);
gaiaFreeGeomColl (geo);
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolatePoint (gaiaGeomCollPtr geom, double fraction)
{
/*
* attempts to intepolate a point on line at dist "fraction"
*
* the fraction is expressed into the range from 0.0 to 1.0
*/
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSGeometry *g;
GEOSGeometry *g_pt;
double length;
double projection;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
/* checking if a single Linestring has been passed */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 1 && pgs == 0)
;
else
return NULL;
g = gaiaToGeos (geom);
if (GEOSLength (g, &length))
{
/* transforming fraction to length */
if (fraction < 0.0)
fraction = 0.0;
if (fraction > 1.0)
fraction = 1.0;
projection = length * fraction;
}
else
{
GEOSGeom_destroy (g);
return NULL;
}
g_pt = GEOSInterpolate (g, projection);
GEOSGeom_destroy (g);
if (!g_pt)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g_pt);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g_pt);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g_pt);
else
result = gaiaFromGeos_XY (g_pt);
GEOSGeom_destroy (g_pt);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL || fraction == 0.0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolatePoint_r (const void *p_cache, gaiaGeomCollPtr geom,
double fraction)
{
/*
* attempts to intepolate a point on line at dist "fraction"
*
* the fraction is expressed into the range from 0.0 to 1.0
*/
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaGeomCollPtr result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSGeometry *g;
GEOSGeometry *g_pt;
double length;
double projection;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
/* checking if a single Linestring has been passed */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 1 && pgs == 0)
;
else
return NULL;
g = gaiaToGeos_r (cache, geom);
if (GEOSLength_r (handle, g, &length))
{
/* transforming fraction to length */
if (fraction < 0.0)
fraction = 0.0;
if (fraction > 1.0)
fraction = 1.0;
projection = length * fraction;
}
else
{
GEOSGeom_destroy_r (handle, g);
return NULL;
}
g_pt = GEOSInterpolate_r (handle, g, projection);
GEOSGeom_destroy_r (handle, g);
if (!g_pt)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g_pt);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g_pt);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g_pt);
else
result = gaiaFromGeos_XY_r (cache, g_pt);
GEOSGeom_destroy_r (handle, g_pt);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
static gaiaGeomCollPtr
gaiaLineInterpolateEquidistantPointsCommon (struct splite_internal_cache *cache,
gaiaGeomCollPtr geom,
double distance)
{
/*
* attempts to intepolate a set of points on line at regular distances
*/
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaGeomCollPtr result;
gaiaGeomCollPtr xpt;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSGeometry *g;
GEOSGeometry *g_pt;
double length;
double current_length = 0.0;
GEOSContextHandle_t handle = NULL;
if (cache != NULL)
{
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
}
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!geom)
return NULL;
if (distance <= 0.0)
return NULL;
/* checking if a single Linestring has been passed */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 1 && pgs == 0)
;
else
return NULL;
if (cache != NULL)
{
g = gaiaToGeos_r (cache, geom);
if (GEOSLength_r (handle, g, &length))
{
if (length <= distance)
{
/* the line is too short to apply interpolation */
GEOSGeom_destroy_r (handle, g);
return NULL;
}
}
else
{
GEOSGeom_destroy_r (handle, g);
return NULL;
}
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
g = gaiaToGeos (geom);
if (GEOSLength (g, &length))
{
if (length <= distance)
{
/* the line is too short to apply interpolation */
GEOSGeom_destroy (g);
return NULL;
}
}
else
{
GEOSGeom_destroy (g);
return NULL;
}
#endif
}
/* creating the MultiPoint [always supporting M] */
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomCollXYM ();
if (result == NULL)
{
if (cache != NULL)
{
GEOSGeom_destroy_r (handle, g);
return NULL;
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeom_destroy (g);
return NULL;
#endif
}
}
while (1)
{
/* increasing the current distance */
current_length += distance;
if (current_length >= length)
break;
/* interpolating a point */
if (handle != NULL)
g_pt = GEOSInterpolate_r (handle, g, current_length);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
g_pt = GEOSInterpolate (g, current_length);
#endif
if (!g_pt)
goto error;
if (geom->DimensionModel == GAIA_XY_Z)
{
if (cache != NULL)
xpt = gaiaFromGeos_XYZ_r (cache, g_pt);
else
xpt = gaiaFromGeos_XYZ (g_pt);
if (!xpt)
goto error;
pt = xpt->FirstPoint;
if (!pt)
goto error;
gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z,
current_length);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
if (cache != NULL)
xpt = gaiaFromGeos_XYM_r (cache, g_pt);
else
xpt = gaiaFromGeos_XYM (g_pt);
if (!xpt)
goto error;
pt = xpt->FirstPoint;
if (!pt)
goto error;
gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y,
current_length);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (cache != NULL)
xpt = gaiaFromGeos_XYZM_r (cache, g_pt);
else
xpt = gaiaFromGeos_XYZM (g_pt);
if (!xpt)
goto error;
pt = xpt->FirstPoint;
if (!pt)
goto error;
gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z,
current_length);
}
else
{
if (cache != NULL)
xpt = gaiaFromGeos_XY_r (cache, g_pt);
else
xpt = gaiaFromGeos_XY (g_pt);
if (!xpt)
goto error;
pt = xpt->FirstPoint;
if (!pt)
goto error;
gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y,
current_length);
}
if (handle != NULL)
GEOSGeom_destroy_r (handle, g_pt);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
GEOSGeom_destroy (g_pt);
#endif
gaiaFreeGeomColl (xpt);
}
if (handle != NULL)
GEOSGeom_destroy_r (handle, g);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
GEOSGeom_destroy (g);
#endif
result->Srid = geom->Srid;
result->DeclaredType = GAIA_MULTIPOINT;
return result;
error:
if (handle != NULL)
{
if (g_pt)
GEOSGeom_destroy_r (handle, g_pt);
GEOSGeom_destroy_r (handle, g);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (g_pt)
GEOSGeom_destroy (g_pt);
GEOSGeom_destroy (g);
#endif
}
gaiaFreeGeomColl (result);
return NULL;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolateEquidistantPoints (gaiaGeomCollPtr geom, double distance)
{
gaiaResetGeosMsg ();
return gaiaLineInterpolateEquidistantPointsCommon (NULL, geom, distance);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineInterpolateEquidistantPoints_r (const void *p_cache,
gaiaGeomCollPtr geom, double distance)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
return gaiaLineInterpolateEquidistantPointsCommon (cache, geom, distance);
}
GAIAGEO_DECLARE double
gaiaLineLocatePoint (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/*
* attempts to compute the location of the closest point on LineString
* to the given Point, as a fraction of total 2d line length
*
* the fraction is expressed into the range from 0.0 to 1.0
*/
double result = -1.0;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
int pts1 = 0;
int lns1 = 0;
int pgs1 = 0;
int pts2 = 0;
int lns2 = 0;
int pgs2 = 0;
double length;
double projection;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return -1.0;
/* checking if a single Linestring has been passed */
pt = geom1->FirstPoint;
while (pt)
{
pts1++;
pt = pt->Next;
}
ln = geom1->FirstLinestring;
while (ln)
{
lns1++;
ln = ln->Next;
}
pg = geom1->FirstPolygon;
while (pg)
{
pgs1++;
pg = pg->Next;
}
if (pts1 == 0 && lns1 >= 1 && pgs1 == 0)
;
else
return -1.0;
/* checking if a single Point has been passed */
pt = geom2->FirstPoint;
while (pt)
{
pts2++;
pt = pt->Next;
}
ln = geom2->FirstLinestring;
while (ln)
{
lns2++;
ln = ln->Next;
}
pg = geom2->FirstPolygon;
while (pg)
{
pgs2++;
pg = pg->Next;
}
if (pts2 == 1 && lns2 == 0 && pgs2 == 0)
;
else
return -1.0;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
projection = GEOSProject (g1, g2);
if (GEOSLength (g1, &length))
{
/* normalizing as a fraction between 0.0 and 1.0 */
result = projection / length;
}
else
result = -1.0;
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
#else
if (geom1 == NULL || geom2 == NULL)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE double
gaiaLineLocatePoint_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
/*
* attempts to compute the location of the closest point on LineString
* to the given Point, as a fraction of total 2d line length
*
* the fraction is expressed into the range from 0.0 to 1.0
*/
int pts1 = 0;
int lns1 = 0;
int pgs1 = 0;
int pts2 = 0;
int lns2 = 0;
int pgs2 = 0;
double length;
double projection;
double result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
GEOSGeometry *g1;
GEOSGeometry *g2;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return -1.0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return -1.0;
handle = cache->GEOS_handle;
if (handle == NULL)
return -1.0;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return -1.0;
/* checking if a single Linestring has been passed */
pt = geom1->FirstPoint;
while (pt)
{
pts1++;
pt = pt->Next;
}
ln = geom1->FirstLinestring;
while (ln)
{
lns1++;
ln = ln->Next;
}
pg = geom1->FirstPolygon;
while (pg)
{
pgs1++;
pg = pg->Next;
}
if (pts1 == 0 && lns1 >= 1 && pgs1 == 0)
;
else
return -1.0;
/* checking if a single Point has been passed */
pt = geom2->FirstPoint;
while (pt)
{
pts2++;
pt = pt->Next;
}
ln = geom2->FirstLinestring;
while (ln)
{
lns2++;
ln = ln->Next;
}
pg = geom2->FirstPolygon;
while (pg)
{
pgs2++;
pg = pg->Next;
}
if (pts2 == 1 && lns2 == 0 && pgs2 == 0)
;
else
return -1.0;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
projection = GEOSProject_r (handle, g1, g2);
if (GEOSLength_r (handle, g1, &length))
{
/* normalizing as a fraction between 0.0 and 1.0 */
result = projection / length;
}
else
result = -1.0;
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
return result;
}
static gaiaGeomCollPtr
gaiaLineSubstringCommon (struct splite_internal_cache *cache,
gaiaGeomCollPtr geom, double start_fraction,
double end_fraction)
{
/*
* attempts to build a new Linestring being a substring of the input one starting
* and ending at the given fractions of total 2d length
*/
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaGeomCollPtr result;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr out;
gaiaPolygonPtr pg;
GEOSGeometry *g;
GEOSGeometry *g_start;
GEOSGeometry *g_end;
GEOSCoordSequence *cs;
const GEOSCoordSequence *in_cs;
GEOSGeometry *segm;
double length;
double total = 0.0;
double start;
double end;
int iv;
int i_start = -1;
int i_end = -1;
int points;
double x;
double y;
double z;
double m;
double x0;
double y0;
unsigned int dims;
GEOSContextHandle_t handle = NULL;
if (cache != NULL)
{
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
}
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!geom)
return NULL;
/* checking if a single Linestring has been passed */
pt = geom->FirstPoint;
while (pt)
{
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 1 && pgs == 0)
;
else
return NULL;
if (start_fraction < 0.0)
start_fraction = 0.0;
if (start_fraction > 1.0)
start_fraction = 1.0;
if (end_fraction < 0.0)
end_fraction = 0.0;
if (end_fraction > 1.0)
end_fraction = 1.0;
if (start_fraction >= end_fraction)
return NULL;
if (cache != NULL)
{
g = gaiaToGeos_r (cache, geom);
if (GEOSLength_r (handle, g, &length))
{
start = length * start_fraction;
end = length * end_fraction;
}
else
{
GEOSGeom_destroy_r (handle, g);
return NULL;
}
g_start = GEOSInterpolate_r (handle, g, start);
g_end = GEOSInterpolate_r (handle, g, end);
GEOSGeom_destroy_r (handle, g);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
g = gaiaToGeos (geom);
if (GEOSLength (g, &length))
{
start = length * start_fraction;
end = length * end_fraction;
}
else
{
GEOSGeom_destroy (g);
return NULL;
}
g_start = GEOSInterpolate (g, start);
g_end = GEOSInterpolate (g, end);
GEOSGeom_destroy (g);
#endif
}
if (!g_start || !g_end)
return NULL;
/* identifying first and last valid vertex */
x0 = 0.0;
y0 = 0.0;
ln = geom->FirstLinestring;
for (iv = 0; iv < ln->Points; iv++)
{
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
};
if (iv > 0)
{
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 2, 2);
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
segm = GEOSGeom_createLineString_r (handle, cs);
GEOSLength_r (handle, segm, &length);
total += length;
GEOSGeom_destroy_r (handle, segm);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (2, 2);
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
segm = GEOSGeom_createLineString (cs);
GEOSLength (segm, &length);
total += length;
GEOSGeom_destroy (segm);
#endif
}
if (total > start && i_start < 0)
i_start = iv;
if (total < end)
i_end = iv;
}
x0 = x;
y0 = y;
}
if (i_start < 0 || i_end < 0)
{
i_start = -1;
i_end = -1;
points = 2;
}
else
points = i_end - i_start + 3;
/* creating the output geometry */
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
result = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
result = gaiaAllocGeomCollXYM ();
break;
case GAIA_XY_Z_M:
result = gaiaAllocGeomCollXYZM ();
break;
default:
result = gaiaAllocGeomColl ();
break;
};
result->Srid = geom->Srid;
out = gaiaAddLinestringToGeomColl (result, points);
/* start vertex */
points = 0;
if (handle)
{
in_cs = GEOSGeom_getCoordSeq_r (handle, g_start);
GEOSCoordSeq_getDimensions_r (handle, in_cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle, in_cs, 0, &x);
GEOSCoordSeq_getY_r (handle, in_cs, 0, &y);
GEOSCoordSeq_getZ_r (handle, in_cs, 0, &z);
m = 0.0;
}
else
{
GEOSCoordSeq_getX_r (handle, in_cs, 0, &x);
GEOSCoordSeq_getY_r (handle, in_cs, 0, &y);
z = 0.0;
m = 0.0;
}
GEOSGeom_destroy_r (handle, g_start);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
in_cs = GEOSGeom_getCoordSeq (g_start);
GEOSCoordSeq_getDimensions (in_cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX (in_cs, 0, &x);
GEOSCoordSeq_getY (in_cs, 0, &y);
GEOSCoordSeq_getZ (in_cs, 0, &z);
m = 0.0;
}
else
{
GEOSCoordSeq_getX (in_cs, 0, &x);
GEOSCoordSeq_getY (in_cs, 0, &y);
z = 0.0;
m = 0.0;
}
GEOSGeom_destroy (g_start);
#endif
}
switch (out->DimensionModel)
{
case GAIA_XY_Z:
gaiaSetPointXYZ (out->Coords, points, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (out->Coords, points, x, y, 0.0);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (out->Coords, points, x, y, z, 0.0);
break;
default:
gaiaSetPoint (out->Coords, points, x, y);
break;
};
points++;
if (i_start < 0 || i_end < 0)
;
else
{
for (iv = i_start; iv <= i_end; iv++)
{
z = 0.0;
m = 0.0;
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
};
switch (out->DimensionModel)
{
case GAIA_XY_Z:
gaiaSetPointXYZ (out->Coords, points, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (out->Coords, points, x, y, 0.0);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (out->Coords, points, x, y, z, 0.0);
break;
default:
gaiaSetPoint (out->Coords, points, x, y);
break;
};
points++;
}
}
/* end vertex */
if (handle != NULL)
{
in_cs = GEOSGeom_getCoordSeq_r (handle, g_end);
GEOSCoordSeq_getDimensions_r (handle, in_cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle, in_cs, 0, &x);
GEOSCoordSeq_getY_r (handle, in_cs, 0, &y);
GEOSCoordSeq_getZ_r (handle, in_cs, 0, &z);
m = 0.0;
}
else
{
GEOSCoordSeq_getX_r (handle, in_cs, 0, &x);
GEOSCoordSeq_getY_r (handle, in_cs, 0, &y);
z = 0.0;
m = 0.0;
}
GEOSGeom_destroy_r (handle, g_end);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
in_cs = GEOSGeom_getCoordSeq (g_end);
GEOSCoordSeq_getDimensions (in_cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX (in_cs, 0, &x);
GEOSCoordSeq_getY (in_cs, 0, &y);
GEOSCoordSeq_getZ (in_cs, 0, &z);
m = 0.0;
}
else
{
GEOSCoordSeq_getX (in_cs, 0, &x);
GEOSCoordSeq_getY (in_cs, 0, &y);
z = 0.0;
m = 0.0;
}
GEOSGeom_destroy (g_end);
#endif
}
switch (out->DimensionModel)
{
case GAIA_XY_Z:
gaiaSetPointXYZ (out->Coords, points, x, y, z);
break;
case GAIA_XY_M:
gaiaSetPointXYM (out->Coords, points, x, y, 0.0);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (out->Coords, points, x, y, z, 0.0);
break;
default:
gaiaSetPoint (out->Coords, points, x, y);
break;
};
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineSubstring (gaiaGeomCollPtr geom, double start_fraction,
double end_fraction)
{
gaiaResetGeosMsg ();
return gaiaLineSubstringCommon (NULL, geom, start_fraction, end_fraction);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineSubstring_r (const void *p_cache, gaiaGeomCollPtr geom,
double start_fraction, double end_fraction)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
return gaiaLineSubstringCommon (cache, geom, start_fraction, end_fraction);
}
static GEOSGeometry *
buildGeosPoints (GEOSContextHandle_t handle, const gaiaGeomCollPtr gaia)
{
/* converting a GAIA Geometry into a GEOS Geometry of POINTS */
int pts = 0;
unsigned int dims;
int iv;
int ib;
int nItem;
double x;
double y;
double z;
double m;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
GEOSGeometry *geos = NULL;
GEOSGeometry *geos_item;
GEOSGeometry **geos_coll;
GEOSCoordSequence *cs;
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!gaia)
return NULL;
pt = gaia->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = gaia->FirstLinestring;
while (ln)
{
/* counting how many POINTs are there */
pts += ln->Points;
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
/* counting how many POINTs are there */
rng = pg->Exterior;
pts += rng->Points - 1; /* exterior ring */
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
pts += rng->Points - 1;
}
pg = pg->Next;
}
if (pts == 0)
return NULL;
switch (gaia->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
dims = 3;
break;
default:
dims = 2;
break;
};
nItem = 0;
geos_coll = malloc (sizeof (GEOSGeometry *) * (pts));
pt = gaia->FirstPoint;
while (pt)
{
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 1, dims);
switch (pt->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
GEOSCoordSeq_setZ_r (handle, cs, 0, pt->Z);
break;
default:
GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
break;
};
geos_item = GEOSGeom_createPoint_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (1, dims);
switch (pt->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
GEOSCoordSeq_setZ (cs, 0, pt->Z);
break;
default:
GEOSCoordSeq_setX (cs, 0, pt->X);
GEOSCoordSeq_setY (cs, 0, pt->Y);
break;
};
geos_item = GEOSGeom_createPoint (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
pt = pt->Next;
}
ln = gaia->FirstLinestring;
while (ln)
{
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
m = 0.0;
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
};
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
GEOSCoordSeq_setZ_r (handle, cs, 0, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
}
geos_item = GEOSGeom_createPoint_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
GEOSCoordSeq_setZ (cs, 0, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
}
geos_item = GEOSGeom_createPoint (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
for (iv = 1; iv < rng->Points; iv++)
{
/* exterior ring */
z = 0.0;
m = 0.0;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
break;
};
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
GEOSCoordSeq_setZ_r (handle, cs, 0, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
}
geos_item = GEOSGeom_createPoint_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
GEOSCoordSeq_setZ (cs, 0, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
}
geos_item = GEOSGeom_createPoint (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
for (iv = 1; iv < rng->Points; iv++)
{
/* exterior ring */
z = 0.0;
m = 0.0;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
break;
};
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
GEOSCoordSeq_setZ_r (handle, cs, 0, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x);
GEOSCoordSeq_setY_r (handle, cs, 0, y);
}
geos_item = GEOSGeom_createPoint_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (1, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
GEOSCoordSeq_setZ (cs, 0, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x);
GEOSCoordSeq_setY (cs, 0, y);
}
geos_item = GEOSGeom_createPoint (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
}
pg = pg->Next;
}
if (handle != NULL)
{
geos =
GEOSGeom_createCollection_r (handle, GEOS_MULTIPOINT, geos_coll,
pts);
free (geos_coll);
GEOSSetSRID_r (handle, geos, gaia->Srid);
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
geos = GEOSGeom_createCollection (GEOS_MULTIPOINT, geos_coll, pts);
free (geos_coll);
GEOSSetSRID (geos, gaia->Srid);
}
#endif
return geos;
}
static GEOSGeometry *
buildGeosSegments (GEOSContextHandle_t handle, const gaiaGeomCollPtr gaia)
{
/* converting a GAIA Geometry into a GEOS Geometry of SEGMENTS */
int segms = 0;
unsigned int dims;
int iv;
int ib;
int nItem;
double x;
double y;
double z;
double m;
double x0 = 0.0;
double y0 = 0.0;
double z0 = 0.0;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
GEOSGeometry *geos = NULL;
GEOSGeometry *geos_item;
GEOSGeometry **geos_coll;
GEOSCoordSequence *cs;
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!gaia)
return NULL;
ln = gaia->FirstLinestring;
while (ln)
{
/* counting how many SEGMENTs are there */
segms += ln->Points - 1;
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
/* counting how many SEGMENTs are there */
rng = pg->Exterior;
segms += rng->Points - 1; /* exterior ring */
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
segms += rng->Points - 1;
}
pg = pg->Next;
}
if (segms == 0)
return NULL;
switch (gaia->DimensionModel)
{
case GAIA_XY_Z:
case GAIA_XY_Z_M:
dims = 3;
break;
default:
dims = 2;
break;
};
nItem = 0;
geos_coll = malloc (sizeof (GEOSGeometry *) * (segms));
ln = gaia->FirstLinestring;
while (ln)
{
for (iv = 0; iv < ln->Points; iv++)
{
z = 0.0;
m = 0.0;
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (ln->Coords, iv, &x, &y);
break;
};
if (iv > 0)
{
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setZ_r (handle, cs, 0, z0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
GEOSCoordSeq_setZ_r (handle, cs, 1, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
}
geos_item =
GEOSGeom_createLineString_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setZ (cs, 0, z0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
GEOSCoordSeq_setZ (cs, 1, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
}
geos_item = GEOSGeom_createLineString (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
x0 = x;
y0 = y;
z0 = z;
}
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
for (iv = 0; iv < rng->Points; iv++)
{
/* exterior ring */
z = 0.0;
m = 0.0;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
break;
};
if (iv > 0)
{
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setZ_r (handle, cs, 0, z0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
GEOSCoordSeq_setZ_r (handle, cs, 1, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
}
geos_item =
GEOSGeom_createLineString_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setZ (cs, 0, z0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
GEOSCoordSeq_setZ (cs, 1, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
}
geos_item = GEOSGeom_createLineString (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
x0 = x;
y0 = y;
z0 = z;
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* interior ring */
rng = pg->Interiors + ib;
for (iv = 0; iv < rng->Points; iv++)
{
/* exterior ring */
z = 0.0;
m = 0.0;
switch (rng->DimensionModel)
{
case GAIA_XY_Z:
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
break;
case GAIA_XY_M:
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
break;
case GAIA_XY_Z_M:
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
break;
default:
gaiaGetPoint (rng->Coords, iv, &x, &y);
break;
};
if (iv > 0)
{
if (handle != NULL)
{
cs = GEOSCoordSeq_create_r (handle, 2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setZ_r (handle, cs, 0, z0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
GEOSCoordSeq_setZ_r (handle, cs, 1, z);
}
else
{
GEOSCoordSeq_setX_r (handle, cs, 0, x0);
GEOSCoordSeq_setY_r (handle, cs, 0, y0);
GEOSCoordSeq_setX_r (handle, cs, 1, x);
GEOSCoordSeq_setY_r (handle, cs, 1, y);
}
geos_item =
GEOSGeom_createLineString_r (handle, cs);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSCoordSeq_create (2, dims);
if (dims == 3)
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setZ (cs, 0, z0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
GEOSCoordSeq_setZ (cs, 1, z);
}
else
{
GEOSCoordSeq_setX (cs, 0, x0);
GEOSCoordSeq_setY (cs, 0, y0);
GEOSCoordSeq_setX (cs, 1, x);
GEOSCoordSeq_setY (cs, 1, y);
}
geos_item = GEOSGeom_createLineString (cs);
#endif
}
*(geos_coll + nItem++) = geos_item;
}
x0 = x;
y0 = y;
z0 = z;
}
}
pg = pg->Next;
}
if (handle != NULL)
{
geos =
GEOSGeom_createCollection_r (handle, GEOS_MULTILINESTRING,
geos_coll, segms);
free (geos_coll);
GEOSSetSRID_r (handle, geos, gaia->Srid);
}
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
{
geos =
GEOSGeom_createCollection (GEOS_MULTILINESTRING, geos_coll,
segms);
free (geos_coll);
GEOSSetSRID (geos, gaia->Srid);
}
#endif
return geos;
}
static gaiaGeomCollPtr
gaiaShortestLineCommon (struct splite_internal_cache *cache,
gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* attempts to compute the shortest line between two geometries */
GEOSGeometry *g1_points;
GEOSGeometry *g1_segments;
const GEOSGeometry *g1_item;
GEOSGeometry *g2_points;
GEOSGeometry *g2_segments;
const GEOSGeometry *g2_item;
const GEOSCoordSequence *cs;
GEOSGeometry *g_pt;
gaiaGeomCollPtr result = NULL;
gaiaLinestringPtr ln;
int nItems1;
int nItems2;
int it1;
int it2;
unsigned int dims;
double x_ini = 0.0;
double y_ini = 0.0;
double z_ini = 0.0;
double x_fin = 0.0;
double y_fin = 0.0;
double z_fin = 0.0;
double dist;
double min_dist = DBL_MAX;
double projection;
GEOSContextHandle_t handle = NULL;
if (cache != NULL)
{
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
}
#ifdef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (handle == NULL)
return NULL;
#endif
if (!geom1 || !geom2)
return NULL;
g1_points = buildGeosPoints (handle, geom1);
g1_segments = buildGeosSegments (handle, geom1);
g2_points = buildGeosPoints (handle, geom2);
g2_segments = buildGeosSegments (handle, geom2);
if (g1_points && g2_points)
{
/* computing distances between POINTs */
if (handle != NULL)
{
nItems1 = GEOSGetNumGeometries_r (handle, g1_points);
nItems2 = GEOSGetNumGeometries_r (handle, g2_points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
nItems1 = GEOSGetNumGeometries (g1_points);
nItems2 = GEOSGetNumGeometries (g2_points);
#endif
}
for (it1 = 0; it1 < nItems1; it1++)
{
if (handle != NULL)
g1_item = GEOSGetGeometryN_r (handle, g1_points, it1);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
g1_item = GEOSGetGeometryN (g1_points, it1);
#endif
for (it2 = 0; it2 < nItems2; it2++)
{
int distret;
if (handle != NULL)
{
g2_item =
GEOSGetGeometryN_r (handle, g2_points, it2);
distret =
GEOSDistance_r (handle, g1_item, g2_item,
&dist);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
g2_item = GEOSGetGeometryN (g2_points, it2);
distret = GEOSDistance (g1_item, g2_item, &dist);
#endif
}
if (distret)
{
if (dist < min_dist)
{
/* saving min-dist points */
min_dist = dist;
if (handle != NULL)
{
cs = GEOSGeom_getCoordSeq_r (handle,
g1_item);
GEOSCoordSeq_getDimensions_r (handle,
cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle, cs,
0, &x_ini);
GEOSCoordSeq_getY_r (handle, cs,
0, &y_ini);
GEOSCoordSeq_getZ_r (handle, cs,
0, &z_ini);
}
else
{
GEOSCoordSeq_getX_r (handle, cs,
0, &x_ini);
GEOSCoordSeq_getY_r (handle, cs,
0, &y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq_r (handle,
g2_item);
GEOSCoordSeq_getDimensions_r (handle,
cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle, cs,
0, &x_fin);
GEOSCoordSeq_getY_r (handle, cs,
0, &y_fin);
GEOSCoordSeq_getZ_r (handle, cs,
0, &z_fin);
}
else
{
GEOSCoordSeq_getX_r (handle, cs,
0, &x_fin);
GEOSCoordSeq_getY_r (handle, cs,
0, &y_fin);
z_fin = 0.0;
}
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
cs = GEOSGeom_getCoordSeq (g1_item);
GEOSCoordSeq_getDimensions (cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0, &x_ini);
GEOSCoordSeq_getY (cs, 0, &y_ini);
GEOSCoordSeq_getZ (cs, 0, &z_ini);
}
else
{
GEOSCoordSeq_getX (cs, 0, &x_ini);
GEOSCoordSeq_getY (cs, 0, &y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq (g2_item);
GEOSCoordSeq_getDimensions (cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0, &x_fin);
GEOSCoordSeq_getY (cs, 0, &y_fin);
GEOSCoordSeq_getZ (cs, 0, &z_fin);
}
else
{
GEOSCoordSeq_getX (cs, 0, &x_fin);
GEOSCoordSeq_getY (cs, 0, &y_fin);
z_fin = 0.0;
}
#endif
}
}
}
}
}
}
if (g1_points && g2_segments)
{
/* computing distances between POINTs (g1) and SEGMENTs (g2) */
if (handle != NULL)
{
nItems1 = GEOSGetNumGeometries_r (handle, g1_points);
nItems2 = GEOSGetNumGeometries_r (handle, g2_segments);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
nItems1 = GEOSGetNumGeometries (g1_points);
nItems2 = GEOSGetNumGeometries (g2_segments);
#endif
}
for (it1 = 0; it1 < nItems1; it1++)
{
if (handle != NULL)
g1_item = GEOSGetGeometryN_r (handle, g1_points, it1);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
g1_item = GEOSGetGeometryN (g1_points, it1);
#endif
for (it2 = 0; it2 < nItems2; it2++)
{
int distret;
if (handle != NULL)
{
g2_item =
GEOSGetGeometryN_r (handle, g2_segments, it2);
distret =
GEOSDistance_r (handle, g1_item, g2_item,
&dist);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
g2_item = GEOSGetGeometryN (g2_segments, it2);
distret = GEOSDistance (g1_item, g2_item, &dist);
#endif
}
if (distret)
{
if (dist < min_dist)
{
/* saving min-dist points */
if (handle != NULL)
{
projection =
GEOSProject_r (handle, g2_item,
g1_item);
g_pt =
GEOSInterpolate_r (handle, g2_item,
projection);
if (g_pt)
{
min_dist = dist;
cs = GEOSGeom_getCoordSeq_r
(handle, g1_item);
GEOSCoordSeq_getDimensions_r
(handle, cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_ini);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_ini);
GEOSCoordSeq_getZ_r (handle,
cs, 0,
&z_ini);
}
else
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_ini);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq_r
(handle, g_pt);
GEOSCoordSeq_getDimensions_r
(handle, cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_fin);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_fin);
GEOSCoordSeq_getZ_r (handle,
cs, 0,
&z_fin);
}
else
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_fin);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_fin);
z_fin = 0.0;
}
GEOSGeom_destroy_r (handle, g_pt);
}
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
projection =
GEOSProject (g2_item, g1_item);
g_pt =
GEOSInterpolate (g2_item,
projection);
if (g_pt)
{
min_dist = dist;
cs = GEOSGeom_getCoordSeq
(g1_item);
GEOSCoordSeq_getDimensions (cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0,
&x_ini);
GEOSCoordSeq_getY (cs, 0,
&y_ini);
GEOSCoordSeq_getZ (cs, 0,
&z_ini);
}
else
{
GEOSCoordSeq_getX (cs, 0,
&x_ini);
GEOSCoordSeq_getY (cs, 0,
&y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq (g_pt);
GEOSCoordSeq_getDimensions (cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0,
&x_fin);
GEOSCoordSeq_getY (cs, 0,
&y_fin);
GEOSCoordSeq_getZ (cs, 0,
&z_fin);
}
else
{
GEOSCoordSeq_getX (cs, 0,
&x_fin);
GEOSCoordSeq_getY (cs, 0,
&y_fin);
z_fin = 0.0;
}
GEOSGeom_destroy (g_pt);
}
#endif
}
}
}
}
}
}
if (g1_segments && g2_points)
{
/* computing distances between SEGMENTs (g1) and POINTs (g2) */
if (handle != NULL)
{
nItems1 = GEOSGetNumGeometries_r (handle, g1_segments);
nItems2 = GEOSGetNumGeometries_r (handle, g2_points);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
nItems1 = GEOSGetNumGeometries (g1_segments);
nItems2 = GEOSGetNumGeometries (g2_points);
#endif
}
for (it1 = 0; it1 < nItems1; it1++)
{
if (handle != NULL)
g1_item = GEOSGetGeometryN_r (handle, g1_segments, it1);
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
else
g1_item = GEOSGetGeometryN (g1_segments, it1);
#endif
for (it2 = 0; it2 < nItems2; it2++)
{
int distret;
if (handle != NULL)
{
g2_item =
GEOSGetGeometryN_r (handle, g2_points, it2);
distret =
GEOSDistance_r (handle, g1_item, g2_item,
&dist);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
g2_item = GEOSGetGeometryN (g2_points, it2);
distret = GEOSDistance (g1_item, g2_item, &dist);
#endif
}
if (distret)
{
if (dist < min_dist)
{
/* saving min-dist points */
if (handle != NULL)
{
projection =
GEOSProject_r (handle, g1_item,
g2_item);
g_pt =
GEOSInterpolate_r (handle, g1_item,
projection);
if (g_pt)
{
min_dist = dist;
cs = GEOSGeom_getCoordSeq_r
(handle, g_pt);
GEOSCoordSeq_getDimensions_r
(handle, cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_ini);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_ini);
GEOSCoordSeq_getZ_r (handle,
cs, 0,
&z_ini);
}
else
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_ini);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq_r
(handle, g2_item);
GEOSCoordSeq_getDimensions_r
(handle, cs, &dims);
if (dims == 3)
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_fin);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_fin);
GEOSCoordSeq_getZ_r (handle,
cs, 0,
&z_fin);
}
else
{
GEOSCoordSeq_getX_r (handle,
cs, 0,
&x_fin);
GEOSCoordSeq_getY_r (handle,
cs, 0,
&y_fin);
z_fin = 0.0;
}
GEOSGeom_destroy_r (handle, g_pt);
}
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
projection =
GEOSProject (g1_item, g2_item);
g_pt =
GEOSInterpolate (g1_item,
projection);
if (g_pt)
{
min_dist = dist;
cs = GEOSGeom_getCoordSeq (g_pt);
GEOSCoordSeq_getDimensions (cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0,
&x_ini);
GEOSCoordSeq_getY (cs, 0,
&y_ini);
GEOSCoordSeq_getZ (cs, 0,
&z_ini);
}
else
{
GEOSCoordSeq_getX (cs, 0,
&x_ini);
GEOSCoordSeq_getY (cs, 0,
&y_ini);
z_ini = 0.0;
}
cs = GEOSGeom_getCoordSeq
(g2_item);
GEOSCoordSeq_getDimensions (cs,
&dims);
if (dims == 3)
{
GEOSCoordSeq_getX (cs, 0,
&x_fin);
GEOSCoordSeq_getY (cs, 0,
&y_fin);
GEOSCoordSeq_getZ (cs, 0,
&z_fin);
}
else
{
GEOSCoordSeq_getX (cs, 0,
&x_fin);
GEOSCoordSeq_getY (cs, 0,
&y_fin);
z_fin = 0.0;
}
GEOSGeom_destroy (g_pt);
}
#endif
}
}
}
}
}
}
if (handle != NULL)
{
if (g1_points)
GEOSGeom_destroy_r (handle, g1_points);
if (g1_segments)
GEOSGeom_destroy_r (handle, g1_segments);
if (g2_points)
GEOSGeom_destroy_r (handle, g2_points);
if (g2_segments)
GEOSGeom_destroy_r (handle, g2_segments);
}
else
{
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
if (g1_points)
GEOSGeom_destroy (g1_points);
if (g1_segments)
GEOSGeom_destroy (g1_segments);
if (g2_points)
GEOSGeom_destroy (g2_points);
if (g2_segments)
GEOSGeom_destroy (g2_segments);
#endif
}
if (min_dist == DBL_MAX || min_dist <= 0.0)
return NULL;
/* building the shortest line */
switch (geom1->DimensionModel)
{
case GAIA_XY_Z:
result = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
result = gaiaAllocGeomCollXYM ();
break;
case GAIA_XY_Z_M:
result = gaiaAllocGeomCollXYZM ();
break;
default:
result = gaiaAllocGeomColl ();
break;
};
result->Srid = geom1->Srid;
ln = gaiaAddLinestringToGeomColl (result, 2);
switch (ln->DimensionModel)
{
case GAIA_XY_Z:
gaiaSetPointXYZ (ln->Coords, 0, x_ini, y_ini, z_ini);
gaiaSetPointXYZ (ln->Coords, 1, x_fin, y_fin, z_fin);
break;
case GAIA_XY_M:
gaiaSetPointXYM (ln->Coords, 0, x_ini, y_ini, 0.0);
gaiaSetPointXYM (ln->Coords, 1, x_fin, y_fin, 0.0);
break;
case GAIA_XY_Z_M:
gaiaSetPointXYZM (ln->Coords, 0, x_ini, y_ini, z_ini, 0.0);
gaiaSetPointXYZM (ln->Coords, 1, x_fin, y_fin, z_fin, 0.0);
break;
default:
gaiaSetPoint (ln->Coords, 0, x_ini, y_ini);
gaiaSetPoint (ln->Coords, 1, x_fin, y_fin);
break;
};
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaShortestLine (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
gaiaResetGeosMsg ();
return gaiaShortestLineCommon (NULL, geom1, geom2);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaShortestLine_r (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
return gaiaShortestLineCommon (cache, geom1, geom2);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSnap (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2, double tolerance)
{
/* attempts to "snap" geom1 on geom2 using the given tolerance */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaResetGeosMsg ();
if (!geom1 || !geom2)
return NULL;
g1 = gaiaToGeos (geom1);
g2 = gaiaToGeos (geom2);
g3 = GEOSSnap (g1, g2, tolerance);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (g2);
if (!g3)
return NULL;
if (geom1->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g3);
else if (geom1->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g3);
else
result = gaiaFromGeos_XY (g3);
GEOSGeom_destroy (g3);
if (result == NULL)
return NULL;
result->Srid = geom1->Srid;
#else
if (geom1 == NULL || geom2 == NULL || tolerance == 0.0)
geom1 = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSnap_r (const void *p_cache, gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2,
double tolerance)
{
/* attempts to "snap" geom1 on geom2 using the given tolerance */
GEOSGeometry *g1;
GEOSGeometry *g2;
GEOSGeometry *g3;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom1 || !geom2)
return NULL;
g1 = gaiaToGeos_r (cache, geom1);
g2 = gaiaToGeos_r (cache, geom2);
g3 = GEOSSnap_r (handle, g1, g2, tolerance);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, g2);
if (!g3)
return NULL;
if (geom1->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g3);
else if (geom1->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g3);
else
result = gaiaFromGeos_XY_r (cache, g3);
GEOSGeom_destroy_r (handle, g3);
if (result == NULL)
return NULL;
result->Srid = geom1->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineMerge (gaiaGeomCollPtr geom)
{
/* attempts to reassemble lines from a collection of sparse fragments */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSLineMerge (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineMerge_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* attempts to reassemble lines from a collection of sparse fragments */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSLineMerge_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaUnaryUnion (gaiaGeomCollPtr geom)
{
/* Unary Union (single Collection) */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
if (gaiaIsToxic (geom))
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSUnaryUnion (g1);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
#else
if (geom == NULL)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaUnaryUnion_r (const void *p_cache, gaiaGeomCollPtr geom)
{
/* Unary Union (single Collection) */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
if (gaiaIsToxic_r (cache, geom))
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSUnaryUnion_r (handle, g1);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
return result;
}
static void
rotateRingBeforeCut (gaiaLinestringPtr ln, gaiaPointPtr node)
{
/* rotating a Ring, so to ensure that Start/End points match the node */
int io = 0;
int iv;
int copy = 0;
int base_idx = -1;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
gaiaLinestringPtr new_ln = NULL;
if (ln->DimensionModel == GAIA_XY_Z)
new_ln = gaiaAllocLinestringXYZ (ln->Points);
else if (ln->DimensionModel == GAIA_XY_M)
new_ln = gaiaAllocLinestringXYM (ln->Points);
else if (ln->DimensionModel == GAIA_XY_Z_M)
new_ln = gaiaAllocLinestringXYZM (ln->Points);
else
new_ln = gaiaAllocLinestring (ln->Points);
/* first pass */
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (!copy)
{
if (ln->DimensionModel == GAIA_XY_Z
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (node->X == x && node->Y == y && node->Z == z)
{
base_idx = iv;
copy = 1;
}
}
else if (node->X == x && node->Y == y)
{
base_idx = iv;
copy = 1;
}
}
if (copy)
{
/* copying points */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_ln->Coords, io, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_ln->Coords, io, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_ln->Coords, io, x, y, z, m);
}
else
{
gaiaSetPoint (new_ln->Coords, io, x, y);
}
io++;
}
}
if (base_idx <= 0)
{
gaiaFreeLinestring (new_ln);
return;
}
/* second pass */
for (iv = 1; iv <= base_idx; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_ln->Coords, io, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_ln->Coords, io, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_ln->Coords, io, x, y, z, m);
}
else
{
gaiaSetPoint (new_ln->Coords, io, x, y);
}
io++;
}
/* copying back */
for (iv = 0; iv < new_ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (new_ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (new_ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (new_ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (new_ln->Coords, iv, &x, &y);
}
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
gaiaFreeLinestring (new_ln);
}
static void
extractSubLine (gaiaGeomCollPtr result, gaiaLinestringPtr ln, int i_start,
int i_end)
{
/* extracting s SubLine */
int iv;
int io = 0;
int pts = i_end - i_start + 1;
gaiaLinestringPtr new_ln = NULL;
double x;
double y;
double z;
double m;
new_ln = gaiaAddLinestringToGeomColl (result, pts);
for (iv = i_start; iv <= i_end; iv++)
{
m = 0.0;
z = 0.0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (new_ln->Coords, io, x, y, z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (new_ln->Coords, io, x, y, m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (new_ln->Coords, io, x, y, z, m);
}
else
{
gaiaSetPoint (new_ln->Coords, io, x, y);
}
io++;
}
}
static void
cutLineAtNodes (gaiaLinestringPtr ln, gaiaPointPtr pt_base,
gaiaGeomCollPtr result)
{
/* attempts to cut a single Line accordingly to given nodes */
int closed = 0;
int match = 0;
int iv;
int i_start;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
gaiaPointPtr pt;
gaiaPointPtr node = NULL;
if (gaiaIsClosed (ln))
closed = 1;
/* pre-check */
for (iv = 0; iv < ln->Points; iv++)
{
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
pt = pt_base;
while (pt)
{
if (ln->DimensionModel == GAIA_XY_Z
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (pt->X == x && pt->Y == y && pt->Z == z)
{
node = pt;
match++;
}
}
else if (pt->X == x && pt->Y == y)
{
node = pt;
match++;
}
pt = pt->Next;
}
}
if (closed && node)
rotateRingBeforeCut (ln, node);
i_start = 0;
for (iv = 1; iv < ln->Points - 1; iv++)
{
/* identifying sub-linestrings */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
match = 0;
pt = pt_base;
while (pt)
{
if (ln->DimensionModel == GAIA_XY_Z
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (pt->X == x && pt->Y == y && pt->Z == z)
{
match = 1;
break;
}
}
else if (pt->X == x && pt->Y == y)
{
match = 1;
break;
}
pt = pt->Next;
}
if (match)
{
/* cutting the line */
extractSubLine (result, ln, i_start, iv);
i_start = iv;
}
}
if (i_start != 0 && i_start != ln->Points - 1)
{
/* extracting the last SubLine */
extractSubLine (result, ln, i_start, ln->Points - 1);
}
else
{
/* cloning the untouched Line */
extractSubLine (result, ln, 0, ln->Points - 1);
}
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLinesCutAtNodes (gaiaGeomCollPtr geom1, gaiaGeomCollPtr geom2)
{
/* attempts to cut lines accordingly to nodes */
int pts1 = 0;
int lns1 = 0;
int pgs1 = 0;
int pts2 = 0;
int lns2 = 0;
int pgs2 = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaGeomCollPtr result = NULL;
if (!geom1)
return NULL;
if (!geom2)
return NULL;
/* both Geometryes should have identical Dimensions */
if (geom1->DimensionModel != geom2->DimensionModel)
return NULL;
pt = geom1->FirstPoint;
while (pt)
{
pts1++;
pt = pt->Next;
}
ln = geom1->FirstLinestring;
while (ln)
{
lns1++;
ln = ln->Next;
}
pg = geom1->FirstPolygon;
while (pg)
{
pgs1++;
pg = pg->Next;
}
pt = geom2->FirstPoint;
while (pt)
{
pts2++;
pt = pt->Next;
}
ln = geom2->FirstLinestring;
while (ln)
{
lns2++;
ln = ln->Next;
}
pg = geom2->FirstPolygon;
while (pg)
{
pgs2++;
pg = pg->Next;
}
/* the first Geometry is expected to contain one or more Linestring(s) */
if (pts1 == 0 && lns1 > 0 && pgs1 == 0)
;
else
return NULL;
/* the second Geometry is expected to contain one or more Point(s) */
if (pts2 > 0 && lns2 == 0 && pgs2 == 0)
;
else
return NULL;
/* attempting to cut Lines accordingly to Nodes */
if (geom1->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom1->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom1->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
ln = geom1->FirstLinestring;
while (ln)
{
cutLineAtNodes (ln, geom2->FirstPoint, result);
ln = ln->Next;
}
if (result->FirstLinestring == NULL)
{
gaiaFreeGeomColl (result);
return NULL;
}
result->Srid = geom1->Srid;
return result;
}
#ifdef GEOS_ADVANCED /* GEOS advanced features - 3.4.0 */
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDelaunayTriangulation (gaiaGeomCollPtr geom, double tolerance,
int only_edges)
{
/* Delaunay Triangulation */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSDelaunayTriangulation (g1, tolerance, only_edges);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
if (only_edges)
result->DeclaredType = GAIA_MULTILINESTRING;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
#else
if (geom == NULL || tolerance == 0.0 || only_edges == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaDelaunayTriangulation_r (const void *p_cache, gaiaGeomCollPtr geom,
double tolerance, int only_edges)
{
/* Delaunay Triangulation */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSDelaunayTriangulation_r (handle, g1, tolerance, only_edges);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
result->Srid = geom->Srid;
if (only_edges)
result->DeclaredType = GAIA_MULTILINESTRING;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
return result;
}
#ifdef GEOS_REENTRANT /* only if GEOS >= 3.5.0 directly supporting Voronoj */
static gaiaGeomCollPtr
voronoj_envelope (gaiaGeomCollPtr geom, double extra_frame_size)
{
/* building the extended envelope for Voronoj */
gaiaGeomCollPtr bbox;
gaiaPolygonPtr pg;
gaiaRingPtr rect;
double minx;
double miny;
double maxx;
double maxy;
double ext_x;
double ext_y;
double delta;
double delta2;
gaiaMbrGeometry (geom);
/* setting the frame extent */
if (extra_frame_size < 0.0)
extra_frame_size = 5.0;
ext_x = geom->MaxX - geom->MinX;
ext_y = geom->MaxY - geom->MinY;
delta = (ext_x * extra_frame_size) / 100.0;
delta2 = (ext_y * extra_frame_size) / 100.0;
if (delta2 > delta)
delta = delta2;
minx = geom->MinX - delta;
miny = geom->MinY - delta;
maxx = geom->MaxX + delta;
maxy = geom->MaxY + delta;
/* building the frame */
if (geom->DimensionModel == GAIA_XY_Z)
bbox = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
bbox = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
bbox = gaiaAllocGeomCollXYZM ();
else
bbox = gaiaAllocGeomColl ();
bbox->Srid = geom->Srid;
bbox->DeclaredType = GAIA_POLYGON;
pg = gaiaAddPolygonToGeomColl (bbox, 5, 0);
rect = pg->Exterior;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (rect->Coords, 0, minx, miny, 0.0);
gaiaSetPointXYZ (rect->Coords, 1, maxx, miny, 0.0);
gaiaSetPointXYZ (rect->Coords, 2, maxx, maxy, 0.0);
gaiaSetPointXYZ (rect->Coords, 3, minx, maxy, 0.0);
gaiaSetPointXYZ (rect->Coords, 4, minx, miny, 0.0);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (rect->Coords, 0, minx, miny, 0.0);
gaiaSetPointXYM (rect->Coords, 1, maxx, miny, 0.0);
gaiaSetPointXYM (rect->Coords, 2, maxx, maxy, 0.0);
gaiaSetPointXYM (rect->Coords, 3, minx, maxy, 0.0);
gaiaSetPointXYM (rect->Coords, 4, minx, miny, 0.0);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rect->Coords, 0, minx, miny, 0.0, 0.0);
gaiaSetPointXYZM (rect->Coords, 1, maxx, miny, 0.0, 0.0);
gaiaSetPointXYZM (rect->Coords, 2, maxx, maxy, 0.0, 0.0);
gaiaSetPointXYZM (rect->Coords, 3, minx, maxy, 0.0, 0.0);
gaiaSetPointXYZM (rect->Coords, 4, minx, miny, 0.0, 0.0);
}
else
{
gaiaSetPoint (rect->Coords, 0, minx, miny); /* vertex # 1 */
gaiaSetPoint (rect->Coords, 1, maxx, miny); /* vertex # 2 */
gaiaSetPoint (rect->Coords, 2, maxx, maxy); /* vertex # 3 */
gaiaSetPoint (rect->Coords, 3, minx, maxy); /* vertex # 4 */
gaiaSetPoint (rect->Coords, 4, minx, miny); /* vertex # 5 [same as vertex # 1 to close the polygon] */
}
return bbox;
}
static int
voronoj_mbr_contains (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if MBR#1 fully contains MBR#2 */
if (g2->MinX < g1->MinX)
return 0;
if (g2->MaxX > g1->MaxX)
return 0;
if (g2->MinY < g1->MinY)
return 0;
if (g2->MaxY > g1->MaxY)
return 0;
return 1;
}
static int
voronoj_mbr_overlaps (gaiaGeomCollPtr g1, gaiaGeomCollPtr g2)
{
/* checks if two MBRs do overlap */
if (g1->MaxX < g2->MinX)
return 0;
if (g1->MinX > g2->MaxX)
return 0;
if (g1->MaxY < g2->MinY)
return 0;
if (g1->MinY > g2->MaxY)
return 0;
return 1;
}
static gaiaGeomCollPtr
voronoj_postprocess (struct splite_internal_cache *cache, gaiaGeomCollPtr raw,
gaiaGeomCollPtr envelope, int only_edges)
{
/* postprocessing the result returned by GEOS Voronoj */
gaiaGeomCollPtr candidate;
gaiaGeomCollPtr result;
gaiaGeomCollPtr framed;
gaiaPolygonPtr pg;
gaiaPolygonPtr new_pg;
if (raw->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (raw->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (raw->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
result->Srid = raw->Srid;
result->DeclaredType = GAIA_MULTIPOLYGON;
if (raw->DimensionModel == GAIA_XY_Z)
candidate = gaiaAllocGeomCollXYZ ();
else if (raw->DimensionModel == GAIA_XY_M)
candidate = gaiaAllocGeomCollXYM ();
else if (raw->DimensionModel == GAIA_XY_Z_M)
candidate = gaiaAllocGeomCollXYZM ();
else
candidate = gaiaAllocGeomColl ();
candidate->Srid = raw->Srid;
candidate->DeclaredType = GAIA_POLYGON;
gaiaMbrGeometry (raw);
gaiaMbrGeometry (envelope);
pg = raw->FirstPolygon;
while (pg != NULL)
{
candidate->FirstPolygon = pg;
candidate->LastPolygon = pg;
candidate->MinX = pg->MinX;
candidate->MinY = pg->MinY;
candidate->MaxX = pg->MaxX;
candidate->MaxY = pg->MaxY;
if (voronoj_mbr_contains (envelope, candidate))
{
/* copying a Polygon fully contained within the frame */
new_pg = gaiaClonePolygon (pg);
if (result->FirstPolygon == NULL)
result->FirstPolygon = new_pg;
if (result->LastPolygon != NULL)
result->LastPolygon->Next = new_pg;
result->LastPolygon = new_pg;
}
else if (voronoj_mbr_overlaps (envelope, candidate))
{
/* found a polygon only partially contained within the frame */
new_pg = gaiaClonePolygon (pg);
candidate->FirstPolygon = new_pg;
candidate->LastPolygon = new_pg;
if (cache == NULL)
framed = gaiaGeometryIntersection (envelope, candidate);
else
framed =
gaiaGeometryIntersection_r (cache, envelope, candidate);
candidate->FirstPolygon = NULL;
candidate->LastPolygon = NULL;
gaiaFreePolygon (new_pg);
if (framed)
{
/* copying all framed polygons into the result */
gaiaPolygonPtr pg2 = framed->FirstPolygon;
while (pg2 != NULL)
{
if (result->FirstPolygon == NULL)
result->FirstPolygon = pg2;
if (result->LastPolygon != NULL)
result->LastPolygon->Next = pg2;
result->LastPolygon = pg2;
pg2 = pg2->Next;
}
framed->FirstPolygon = NULL;
framed->LastPolygon = NULL;
gaiaFreeGeomColl (framed);
}
}
pg = pg->Next;
}
candidate->FirstPolygon = NULL;
candidate->LastPolygon = NULL;
gaiaFreeGeomColl (candidate);
gaiaFreeGeomColl (raw);
if (only_edges)
{
gaiaGeomCollPtr lines = gaiaLinearize (result, 1);
gaiaFreeGeomColl (result);
return lines;
}
return result;
}
#endif
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaVoronojDiagram (gaiaGeomCollPtr geom, double extra_frame_size,
double tolerance, int only_edges)
{
/* Voronoj Diagram */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
#ifdef GEOS_REENTRANT
GEOSGeometry *env;
gaiaGeomCollPtr envelope;
#else
void *voronoj;
gaiaPolygonPtr pg;
int pgs = 0;
int errs = 0;
#endif
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
#ifdef GEOS_REENTRANT /* GEOS >= 3.5.0 directly supports Voronoj */
envelope = voronoj_envelope (geom, extra_frame_size);
env = gaiaToGeos (envelope);
g2 = GEOSVoronoiDiagram (g1, env, tolerance, 0);
GEOSGeom_destroy (g1);
GEOSGeom_destroy (env);
if (!g2)
{
gaiaFreeGeomColl (envelope);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
result = voronoj_postprocess (NULL, result, envelope, only_edges);
gaiaFreeGeomColl (envelope);
if (result == NULL)
return NULL;
#else
g2 = GEOSDelaunayTriangulation (g1, tolerance, 0);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
pg = result->FirstPolygon;
while (pg)
{
/* counting how many triangles are in Delaunay */
if (delaunay_triangle_check (pg))
pgs++;
else
errs++;
pg = pg->Next;
}
if (pgs == 0 || errs)
{
gaiaFreeGeomColl (result);
return NULL;
}
/* building the Voronoj Diagram from Delaunay */
voronoj = voronoj_build (pgs, result->FirstPolygon, extra_frame_size);
gaiaFreeGeomColl (result);
/* creating the Geometry representing Voronoj */
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
result = voronoj_export (voronoj, result, only_edges);
voronoj_free (voronoj);
result->Srid = geom->Srid;
if (only_edges)
result->DeclaredType = GAIA_MULTILINESTRING;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
#endif /* end GEOS_REENTRANT */
#else
if (geom == NULL || extra_frame_size == 0.0 || tolerance == 0.0
|| only_edges == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif /* end GEOS_USE_ONLY_R_API */
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaVoronojDiagram_r (const void *p_cache, gaiaGeomCollPtr geom,
double extra_frame_size, double tolerance, int only_edges)
{
/* Voronoj Diagram */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
#ifdef GEOS_REENTRANT
GEOSGeometry *env;
gaiaGeomCollPtr envelope;
#else
gaiaPolygonPtr pg;
int pgs = 0;
int errs = 0;
void *voronoj;
#endif
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
#ifdef GEOS_REENTRANT /* GEOS >= 3.5.0 directly supports Voronoj */
envelope = voronoj_envelope (geom, extra_frame_size);
env = gaiaToGeos_r (cache, envelope);
g2 = GEOSVoronoiDiagram_r (handle, g1, env, tolerance, 0);
GEOSGeom_destroy_r (handle, g1);
GEOSGeom_destroy_r (handle, env);
if (!g2)
{
gaiaFreeGeomColl (envelope);
return NULL;
}
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
result = voronoj_postprocess (cache, result, envelope, only_edges);
gaiaFreeGeomColl (envelope);
if (result == NULL)
return NULL;
#else
g2 = GEOSDelaunayTriangulation_r (handle, g1, tolerance, 0);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
pg = result->FirstPolygon;
while (pg)
{
/* counting how many triangles are in Delaunay */
if (delaunay_triangle_check (pg))
pgs++;
else
errs++;
pg = pg->Next;
}
if (pgs == 0 || errs)
{
gaiaFreeGeomColl (result);
return NULL;
}
/* building the Voronoj Diagram from Delaunay */
voronoj =
voronoj_build_r (cache, pgs, result->FirstPolygon, extra_frame_size);
gaiaFreeGeomColl (result);
/* creating the Geometry representing Voronoj */
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
result = voronoj_export_r (cache, voronoj, result, only_edges);
voronoj_free (voronoj);
result->Srid = geom->Srid;
if (only_edges)
result->DeclaredType = GAIA_MULTILINESTRING;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
#endif /* end GEOS_REENTRANT */
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConcaveHull (gaiaGeomCollPtr geom, double factor, double tolerance,
int allow_holes)
{
/* Concave Hull */
gaiaGeomCollPtr result = NULL;
#ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr concave_hull;
gaiaPolygonPtr pg;
int pgs = 0;
int errs = 0;
gaiaResetGeosMsg ();
if (!geom)
return NULL;
g1 = gaiaToGeos (geom);
g2 = GEOSDelaunayTriangulation (g1, tolerance, 0);
GEOSGeom_destroy (g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ (g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM (g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM (g2);
else
result = gaiaFromGeos_XY (g2);
GEOSGeom_destroy (g2);
if (result == NULL)
return NULL;
pg = result->FirstPolygon;
while (pg)
{
/* counting how many triangles are in Delaunay */
if (delaunay_triangle_check (pg))
pgs++;
else
errs++;
pg = pg->Next;
}
if (pgs == 0 || errs)
{
gaiaFreeGeomColl (result);
return NULL;
}
/* building the Concave Hull from Delaunay */
concave_hull =
concave_hull_build (result->FirstPolygon, geom->DimensionModel, factor,
allow_holes);
gaiaFreeGeomColl (result);
if (!concave_hull)
return NULL;
result = concave_hull;
result->Srid = geom->Srid;
#else
if (geom == NULL || factor == 0.0 || tolerance == 0.0 || allow_holes == 0)
geom = NULL; /* silencing stupid compiler warnings */
#endif
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaConcaveHull_r (const void *p_cache, gaiaGeomCollPtr geom, double factor,
double tolerance, int allow_holes)
{
/* Concave Hull */
GEOSGeometry *g1;
GEOSGeometry *g2;
gaiaGeomCollPtr result;
gaiaGeomCollPtr concave_hull;
gaiaPolygonPtr pg;
int pgs = 0;
int errs = 0;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
GEOSContextHandle_t handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->GEOS_handle;
if (handle == NULL)
return NULL;
gaiaResetGeosMsg_r (cache);
if (!geom)
return NULL;
g1 = gaiaToGeos_r (cache, geom);
g2 = GEOSDelaunayTriangulation_r (handle, g1, tolerance, 0);
GEOSGeom_destroy_r (handle, g1);
if (!g2)
return NULL;
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaFromGeos_XYZ_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaFromGeos_XYM_r (cache, g2);
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaFromGeos_XYZM_r (cache, g2);
else
result = gaiaFromGeos_XY_r (cache, g2);
GEOSGeom_destroy_r (handle, g2);
if (result == NULL)
return NULL;
pg = result->FirstPolygon;
while (pg)
{
/* counting how many triangles are in Delaunay */
if (delaunay_triangle_check (pg))
pgs++;
else
errs++;
pg = pg->Next;
}
if (pgs == 0 || errs)
{
gaiaFreeGeomColl (result);
return NULL;
}
/* building the Concave Hull from Delaunay */
concave_hull =
concave_hull_build_r (p_cache, result->FirstPolygon,
geom->DimensionModel, factor, allow_holes);
gaiaFreeGeomColl (result);
if (!concave_hull)
return NULL;
result = concave_hull;
result->Srid = geom->Srid;
return result;
}
#endif /* end GEOS advanced features */
#endif /* end including GEOS */
libspatialite-5.1.0/src/gaiageo/gg_rttopo.c 0000644 0001750 0001750 00000215137 14463127014 015632 0000000 0000000 /*
gg_rttopo.c -- Gaia RTTOPO support
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2012-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
/*
CREDITS:
this module (wrapping liblwgeom APIs) has been entierely funded by:
Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
HISTORY:
this module was previously name gg_lwgeom.c and was based on liblwgeom;
the current version depends on the newer RTTOPO support
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#include
#include
#ifdef ENABLE_RTTOPO /* enabling RTTOPO support */
#include
extern char *rtgeom_to_encoded_polyline (const RTCTX * ctx, const RTGEOM * geom,
int precision);
static RTGEOM *rtgeom_from_encoded_polyline (const RTCTX * ctx,
const char *encodedpolyline,
int precision);
SPATIALITE_PRIVATE const char *
splite_rttopo_version (void)
{
return rtgeom_version ();
}
GAIAGEO_DECLARE void
gaiaResetRtTopoMsg (const void *p_cache)
{
/* Resets the RTTOPO error and warning messages to an empty state */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return;
if (cache->gaia_rttopo_error_msg)
free (cache->gaia_rttopo_error_msg);
if (cache->gaia_rttopo_warning_msg)
free (cache->gaia_rttopo_warning_msg);
cache->gaia_rttopo_error_msg = NULL;
cache->gaia_rttopo_warning_msg = NULL;
}
GAIAGEO_DECLARE const char *
gaiaGetRtTopoErrorMsg (const void *p_cache)
{
/* Return the latest RTTOPO error message (if any) */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
return cache->gaia_rttopo_error_msg;
}
GAIAGEO_DECLARE void
gaiaSetRtTopoErrorMsg (const void *p_cache, const char *msg)
{
/* Sets the RTTOPO error message */
int len;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return;
if (cache->gaia_rttopo_error_msg)
free (cache->gaia_rttopo_error_msg);
cache->gaia_rttopo_error_msg = NULL;
if (msg == NULL)
return;
len = strlen (msg);
cache->gaia_rttopo_error_msg = malloc (len + 1);
strcpy (cache->gaia_rttopo_error_msg, msg);
}
GAIAGEO_DECLARE const char *
gaiaGetRtTopoWarningMsg (const void *p_cache)
{
/* Return the latest RTTOPO warning message (if any) */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
return cache->gaia_rttopo_warning_msg;
}
GAIAGEO_DECLARE void
gaiaSetRtTopoWarningMsg (const void *p_cache, const char *msg)
{
/* Sets the RTTOPO warning message */
int len;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache == NULL)
return;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return;
if (cache->gaia_rttopo_warning_msg)
free (cache->gaia_rttopo_warning_msg);
cache->gaia_rttopo_warning_msg = NULL;
if (msg == NULL)
return;
len = strlen (msg);
cache->gaia_rttopo_warning_msg = malloc (len + 1);
strcpy (cache->gaia_rttopo_warning_msg, msg);
}
static int
check_unclosed_ring (gaiaRingPtr rng)
{
/* checks if a Ring is closed or not */
double x0;
double y0;
double z0 = 0.0;
double m0 = 0.0;
double x1;
double y1;
double z1 = 0.0;
double m1 = 0.0;
int last = rng->Points - 1;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x0, &y0, &z0);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x0, &y0, &m0);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x0, &y0, &z0, &m0);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x0, &y0);
}
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, last, &x1, &y1, &z1);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, last, &x1, &y1, &m1);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, last, &x1, &y1, &z1, &m1);
}
else
{
gaiaGetPoint (rng->Coords, last, &x1, &y1);
}
if (x0 == x1 && y0 == y1 && z0 == z1 && m0 == m1)
return 0;
return 1;
}
SPATIALITE_PRIVATE void *
toRTGeom (const void *pctx, const void *pgaia)
{
/* converting a GAIA Geometry into a RTGEOM Geometry */
const RTCTX *ctx = (const RTCTX *) pctx;
const gaiaGeomCollPtr gaia = (const gaiaGeomCollPtr) pgaia;
int pts = 0;
int lns = 0;
int pgs = 0;
int has_z;
int has_m;
int ngeoms;
int numg;
int ib;
int iv;
int type;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
int close_ring;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
RTPOINTARRAY *pa;
RTPOINTARRAY **ppaa;
RTPOINT4D point;
RTGEOM **geoms;
if (!gaia)
return NULL;
pt = gaia->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = gaia->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
/* counting how many POLYGONs are there */
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 0 && pgs == 0)
return NULL;
if (pts == 1 && lns == 0 && pgs == 0)
{
/* single Point */
pt = gaia->FirstPoint;
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
pa = ptarray_construct (ctx, has_z, has_m, 1);
point.x = pt->X;
point.y = pt->Y;
if (has_z)
point.z = pt->Z;
if (has_m)
point.m = pt->M;
ptarray_set_point4d (ctx, pa, 0, &point);
return (RTGEOM *) rtpoint_construct (ctx, gaia->Srid, NULL, pa);
}
else if (pts == 0 && lns == 1 && pgs == 0)
{
/* single Linestring */
ln = gaia->FirstLinestring;
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
pa = ptarray_construct (ctx, has_z, has_m, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
/* copying vertices */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, pa, iv, &point);
}
return (RTGEOM *) rtline_construct (ctx, gaia->Srid, NULL, pa);
}
else if (pts == 0 && lns == 0 && pgs == 1)
{
/* single Polygon */
pg = gaia->FirstPolygon;
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
ngeoms = pg->NumInteriors;
ppaa = rtalloc (ctx, sizeof (RTPOINTARRAY *) * (ngeoms + 1));
rng = pg->Exterior;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[0] = ptarray_construct (ctx, has_z, has_m, rng->Points + 1);
else
ppaa[0] = ptarray_construct (ctx, has_z, has_m, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* copying vertices - Exterior Ring */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], rng->Points, &point);
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* copying vertices - Interior Rings */
rng = pg->Interiors + ib;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[1 + ib] =
ptarray_construct (ctx, has_z, has_m, rng->Points + 1);
else
ppaa[1 + ib] =
ptarray_construct (ctx, has_z, has_m, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[1 + ib], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[1 + ib], rng->Points,
&point);
}
}
return (RTGEOM *) rtpoly_construct (ctx, gaia->Srid, NULL, ngeoms + 1,
ppaa);
}
else
{
/* some Collection */
switch (gaia->DeclaredType)
{
case GAIA_POINT:
type = RTPOINTTYPE;
break;
case GAIA_LINESTRING:
type = RTLINETYPE;
break;
case GAIA_POLYGON:
type = RTPOLYGONTYPE;
break;
case GAIA_MULTIPOINT:
type = RTMULTIPOINTTYPE;
break;
case GAIA_MULTILINESTRING:
type = RTMULTILINETYPE;
break;
case GAIA_MULTIPOLYGON:
type = RTMULTIPOLYGONTYPE;
break;
case GAIA_GEOMETRYCOLLECTION:
type = RTCOLLECTIONTYPE;
break;
default:
if (lns == 0 && pgs == 0)
type = RTMULTIPOINTTYPE;
else if (pts == 0 && pgs == 0)
type = RTMULTILINETYPE;
else if (pts == 0 && lns == 0)
type = RTMULTIPOLYGONTYPE;
else
type = RTCOLLECTIONTYPE;
break;
};
numg = pts + lns + pgs;
geoms = rtalloc (ctx, sizeof (RTGEOM *) * numg);
numg = 0;
pt = gaia->FirstPoint;
while (pt)
{
/* copying POINTs */
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
pa = ptarray_construct (ctx, has_z, has_m, 1);
point.x = pt->X;
point.y = pt->Y;
if (has_z)
point.z = pt->Z;
if (has_m)
point.m = pt->M;
ptarray_set_point4d (ctx, pa, 0, &point);
geoms[numg++] =
(RTGEOM *) rtpoint_construct (ctx, gaia->Srid, NULL, pa);
pt = pt->Next;
}
ln = gaia->FirstLinestring;
while (ln)
{
/* copying LINESTRINGs */
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
pa = ptarray_construct (ctx, has_z, has_m, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
/* copying vertices */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, pa, iv, &point);
}
geoms[numg++] =
(RTGEOM *) rtline_construct (ctx, gaia->Srid, NULL, pa);
ln = ln->Next;
}
pg = gaia->FirstPolygon;
while (pg)
{
/* copying POLYGONs */
has_z = 0;
has_m = 0;
if (gaia->DimensionModel == GAIA_XY_Z
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (gaia->DimensionModel == GAIA_XY_M
|| gaia->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
ngeoms = pg->NumInteriors;
ppaa = rtalloc (ctx, sizeof (RTPOINTARRAY *) * (ngeoms + 1));
rng = pg->Exterior;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[0] =
ptarray_construct (ctx, has_z, has_m, rng->Points + 1);
else
ppaa[0] =
ptarray_construct (ctx, has_z, has_m, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* copying vertices - Exterior Ring */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], rng->Points, &point);
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* copying vertices - Interior Rings */
rng = pg->Interiors + ib;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[1 + ib] =
ptarray_construct (ctx, has_z, has_m,
rng->Points + 1);
else
ppaa[1 + ib] =
ptarray_construct (ctx, has_z, has_m,
rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[1 + ib], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (gaia->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (gaia->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (gaia->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[1 + ib], rng->Points,
&point);
}
}
geoms[numg++] =
(RTGEOM *) rtpoly_construct (ctx, gaia->Srid, NULL,
ngeoms + 1, ppaa);
pg = pg->Next;
}
return (RTGEOM *) rtcollection_construct (ctx, type, gaia->Srid, NULL,
numg, geoms);
}
return NULL;
}
static gaiaGeomCollPtr
fromRTGeomIncremental (const RTCTX * ctx, gaiaGeomCollPtr gaia,
const RTGEOM * rtgeom)
{
/* converting a RTGEOM Geometry into a GAIA Geometry */
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int dimension_model = gaia->DimensionModel;
int declared_type = gaia->DeclaredType;
RTGEOM *rtg2 = NULL;
RTPOINT *rtp = NULL;
RTLINE *rtl = NULL;
RTPOLY *rtpoly = NULL;
RTCOLLECTION *rtc = NULL;
RTPOINTARRAY *pa;
RTPOINT4D pt4d;
int has_z;
int has_m;
int iv;
int ib;
int ngeoms;
int ng;
double x;
double y;
double z;
double m;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
switch (rtgeom->type)
{
case RTPOINTTYPE:
rtp = (RTPOINT *) rtgeom;
has_z = 0;
has_m = 0;
pa = rtp->point;
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
rt_getPoint4d_p (ctx, pa, 0, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
else if (dimension_model == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (gaia, x, y, m);
else if (dimension_model == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (gaia, x, y, z, m);
else
gaiaAddPointToGeomColl (gaia, x, y);
if (declared_type == GAIA_MULTIPOINT)
gaia->DeclaredType = GAIA_MULTIPOINT;
else if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_POINT;
break;
case RTLINETYPE:
rtl = (RTLINE *) rtgeom;
has_z = 0;
has_m = 0;
pa = rtl->points;
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
ln = gaiaAddLinestringToGeomColl (gaia, pa->npoints);
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying LINESTRING vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
if (declared_type == GAIA_MULTILINESTRING)
gaia->DeclaredType = GAIA_MULTILINESTRING;
else if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_LINESTRING;
break;
case RTPOLYGONTYPE:
rtpoly = (RTPOLY *) rtgeom;
has_z = 0;
has_m = 0;
pa = rtpoly->rings[0];
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
pg = gaiaAddPolygonToGeomColl (gaia, pa->npoints, rtpoly->nrings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying Exterion Ring vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
for (ib = 1; ib < rtpoly->nrings; ib++)
{
has_z = 0;
has_m = 0;
pa = rtpoly->rings[ib];
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
rng = gaiaAddInteriorRing (pg, ib - 1, pa->npoints);
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying Exterion Ring vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
if (declared_type == GAIA_MULTIPOLYGON)
gaia->DeclaredType = GAIA_MULTIPOLYGON;
else if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_POLYGON;
break;
case RTMULTIPOINTTYPE:
case RTMULTILINETYPE:
case RTMULTIPOLYGONTYPE:
case RTCOLLECTIONTYPE:
if (rtgeom->type == RTMULTIPOINTTYPE)
{
if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_MULTIPOINT;
}
else if (rtgeom->type == RTMULTILINETYPE)
{
if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_MULTILINESTRING;
}
else if (rtgeom->type == RTMULTIPOLYGONTYPE)
{
if (declared_type == GAIA_GEOMETRYCOLLECTION)
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
gaia->DeclaredType = GAIA_MULTIPOLYGON;
}
else
gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
rtc = (RTCOLLECTION *) rtgeom;
ngeoms = rtc->ngeoms;
if (ngeoms == 0)
{
gaiaFreeGeomColl (gaia);
gaia = NULL;
break;
}
for (ng = 0; ng < ngeoms; ++ng)
{
/* looping on elementary geometries */
rtg2 = rtc->geoms[ng];
switch (rtg2->type)
{
case RTPOINTTYPE:
rtp = (RTPOINT *) rtg2;
has_z = 0;
has_m = 0;
pa = rtp->point;
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
rt_getPoint4d_p (ctx, pa, 0, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
else if (dimension_model == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (gaia, x, y, m);
else if (dimension_model == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (gaia, x, y, z, m);
else
gaiaAddPointToGeomColl (gaia, x, y);
break;
case RTLINETYPE:
rtl = (RTLINE *) rtg2;
has_z = 0;
has_m = 0;
pa = rtl->points;
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
ln = gaiaAddLinestringToGeomColl (gaia, pa->npoints);
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying LINESTRING vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (ln->Coords, iv, x, y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ln->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
break;
case RTPOLYGONTYPE:
rtpoly = (RTPOLY *) rtg2;
/*
* sandro 2023-08-22
*
* critical patch required by GEOS 3.12.0
* that declares invalid POLYGONs without any RING
*
*/
if (rtpoly->nrings <= 0)
continue;
/* end sandro 2023-07-22 */
has_z = 0;
has_m = 0;
pa = rtpoly->rings[0];
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
pg = gaiaAddPolygonToGeomColl (gaia, pa->npoints,
rtpoly->nrings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying Exterion Ring vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x, y, z,
m);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
for (ib = 1; ib < rtpoly->nrings; ib++)
{
has_z = 0;
has_m = 0;
pa = rtpoly->rings[ib];
if (RTFLAGS_GET_Z (pa->flags))
has_z = 1;
if (RTFLAGS_GET_M (pa->flags))
has_m = 1;
rng = gaiaAddInteriorRing (pg, ib - 1, pa->npoints);
for (iv = 0; iv < pa->npoints; iv++)
{
/* copying Exterion Ring vertices */
rt_getPoint4d_p (ctx, pa, iv, &pt4d);
x = pt4d.x;
y = pt4d.y;
if (has_z)
z = pt4d.z;
else
z = 0.0;
if (has_m)
m = pt4d.m;
else
m = 0.0;
if (dimension_model == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, x,
y, z);
}
else if (dimension_model == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, x,
y, m);
}
else if (dimension_model == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, x,
y, z, m);
}
else
{
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
break;
};
}
break;
default:
gaiaFreeGeomColl (gaia);
gaia = NULL;
break;
};
return gaia;
}
SPATIALITE_PRIVATE void *
fromRTGeom (const void *pctx, const void *prtgeom, const int dimension_model,
const int declared_type)
{
/* converting a RTGEOM Geometry into a GAIA Geometry */
gaiaGeomCollPtr gaia = NULL;
const RTCTX *ctx = (const RTCTX *) pctx;
const RTGEOM *rtgeom = (const RTGEOM *) prtgeom;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
gaia->DeclaredType = declared_type;
fromRTGeomIncremental (ctx, gaia, rtgeom);
return gaia;
}
static int
check_valid_type (const RTGEOM * rtgeom, int declared_type)
{
/* checking if the geometry type is a valid one */
int ret = 0;
switch (rtgeom->type)
{
case RTPOINTTYPE:
case RTMULTIPOINTTYPE:
if (declared_type == GAIA_POINT || declared_type == GAIA_POINTZ
|| declared_type == GAIA_POINTM || declared_type == GAIA_POINTZM)
ret = 1;
if (declared_type == GAIA_MULTIPOINT
|| declared_type == GAIA_MULTIPOINTZ
|| declared_type == GAIA_MULTIPOINTM
|| declared_type == GAIA_MULTIPOINTZM)
ret = 1;
break;
case RTLINETYPE:
case RTMULTILINETYPE:
if (declared_type == GAIA_LINESTRING
|| declared_type == GAIA_LINESTRINGZ
|| declared_type == GAIA_LINESTRINGM
|| declared_type == GAIA_LINESTRINGZM)
ret = 1;
if (declared_type == GAIA_MULTILINESTRING
|| declared_type == GAIA_MULTILINESTRINGZ
|| declared_type == GAIA_MULTILINESTRINGM
|| declared_type == GAIA_MULTILINESTRINGZM)
ret = 1;
break;
case RTPOLYGONTYPE:
case RTMULTIPOLYGONTYPE:
if (declared_type == GAIA_POLYGON || declared_type == GAIA_POLYGONZ
|| declared_type == GAIA_POLYGONM
|| declared_type == GAIA_POLYGONZM)
ret = 1;
if (declared_type == GAIA_MULTIPOLYGON
|| declared_type == GAIA_MULTIPOLYGONZ
|| declared_type == GAIA_MULTIPOLYGONM
|| declared_type == GAIA_MULTIPOLYGONZM)
ret = 1;
break;
case RTCOLLECTIONTYPE:
if (declared_type == GAIA_GEOMETRYCOLLECTION
|| declared_type == GAIA_GEOMETRYCOLLECTIONZ
|| declared_type == GAIA_GEOMETRYCOLLECTIONM
|| declared_type == GAIA_GEOMETRYCOLLECTIONZM)
ret = 1;
break;
};
return ret;
}
static gaiaGeomCollPtr
fromRTGeomValidated (const RTCTX * ctx, const RTGEOM * rtgeom,
const int dimension_model, const int declared_type)
{
/*
/ converting a RTGEOM Geometry into a GAIA Geometry
/ first collection - validated items
*/
gaiaGeomCollPtr gaia = NULL;
RTGEOM *rtg2 = NULL;
RTCOLLECTION *rtc = NULL;
int ngeoms;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
switch (rtgeom->type)
{
case RTCOLLECTIONTYPE:
rtc = (RTCOLLECTION *) rtgeom;
ngeoms = rtc->ngeoms;
if (ngeoms <= 2)
{
rtg2 = rtc->geoms[0];
if (check_valid_type (rtg2, declared_type))
gaia =
fromRTGeom (ctx, rtg2, dimension_model, declared_type);
}
break;
default:
if (check_valid_type (rtgeom, declared_type))
gaia = fromRTGeom (ctx, rtgeom, dimension_model, declared_type);
if (gaia == NULL)
{
/* Andrea Peri: 2013-05-02 returning anyway the RTGEOM geometry,
/ even if it has a mismatching type */
int type = -1;
switch (rtgeom->type)
{
case RTPOINTTYPE:
type = GAIA_POINT;
break;
case RTLINETYPE:
type = GAIA_LINESTRING;
break;
case RTPOLYGONTYPE:
type = GAIA_POLYGON;
break;
case RTMULTIPOINTTYPE:
type = GAIA_MULTIPOINT;
break;
case RTMULTILINETYPE:
type = GAIA_MULTILINESTRING;
break;
case RTMULTIPOLYGONTYPE:
type = GAIA_MULTIPOLYGON;
break;
};
if (type >= 0)
gaia = fromRTGeom (ctx, rtgeom, dimension_model, type);
}
break;
}
return gaia;
}
static gaiaGeomCollPtr
fromRTGeomDiscarded (const RTCTX * ctx, const RTGEOM * rtgeom,
const int dimension_model, const int declared_type)
{
/*
/ converting a RTGEOM Geometry into a GAIA Geometry
/ second collection - discarded items
*/
gaiaGeomCollPtr gaia = NULL;
RTGEOM *rtg2 = NULL;
RTCOLLECTION *rtc = NULL;
int ngeoms;
int ig;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
if (rtgeom->type == RTCOLLECTIONTYPE)
{
if (dimension_model == GAIA_XY_Z)
gaia = gaiaAllocGeomCollXYZ ();
else if (dimension_model == GAIA_XY_M)
gaia = gaiaAllocGeomCollXYM ();
else if (dimension_model == GAIA_XY_Z_M)
gaia = gaiaAllocGeomCollXYZM ();
else
gaia = gaiaAllocGeomColl ();
rtc = (RTCOLLECTION *) rtgeom;
ngeoms = rtc->ngeoms;
for (ig = 0; ig < ngeoms; ig++)
{
rtg2 = rtc->geoms[ig];
if (!check_valid_type (rtg2, declared_type))
fromRTGeomIncremental (ctx, gaia, rtg2);
}
}
/*
Andrea Peri: 2013-05-02
when a single geometry is returned by RTGEOM it's always "valid"
and there are no discarded items at all
else if (!check_valid_type (lwgeom, declared_type))
gaia = fromRTGeom (lwgeom, dimension_model, declared_type);
*/
return gaia;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeValid (const void *p_cache, gaiaGeomCollPtr geom)
{
/* wrapping RTGEOM MakeValid [collecting valid items] */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
gaiaGeomCollPtr result = NULL;
if (!geom)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, geom);
g2 = rtgeom_make_valid (ctx, g1);
if (!g2)
{
rtgeom_free (ctx, g1);
goto done;
}
result =
fromRTGeomValidated (ctx, g2, geom->DimensionModel, geom->DeclaredType);
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
result->Srid = geom->Srid;
done:
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeValidDiscarded (const void *p_cache, gaiaGeomCollPtr geom)
{
/* wrapping RTGEOM MakeValid [collecting discarder items] */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
gaiaGeomCollPtr result = NULL;
if (!geom)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, geom);
g2 = rtgeom_make_valid (ctx, g1);
if (!g2)
{
rtgeom_free (ctx, g1);
goto done;
}
result =
fromRTGeomDiscarded (ctx, g2, geom->DimensionModel, geom->DeclaredType);
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
result->Srid = geom->Srid;
done:
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSegmentize (const void *p_cache, gaiaGeomCollPtr geom, double dist)
{
/* wrapping RTGEOM Segmentize */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
gaiaGeomCollPtr result = NULL;
if (!geom)
return NULL;
if (dist <= 0.0)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, geom);
g2 = rtgeom_segmentize2d (ctx, g1, dist);
if (!g2)
{
rtgeom_free (ctx, g1);
goto done;
}
result = fromRTGeom (ctx, g2, geom->DimensionModel, geom->DeclaredType);
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
result->Srid = geom->Srid;
done:
return result;
}
static int
check_split_args (gaiaGeomCollPtr input, gaiaGeomCollPtr blade)
{
/* testing Split arguments */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int i_lns = 0;
int i_pgs = 0;
int b_pts = 0;
int b_lns = 0;
if (!input)
return 0;
if (!blade)
return 0;
/* testing the Input type */
if (input->FirstPoint != NULL)
{
/* Point(s) on Input is forbidden !!!! */
return 0;
}
ln = input->FirstLinestring;
while (ln)
{
/* counting how many Linestrings are there */
i_lns++;
ln = ln->Next;
}
pg = input->FirstPolygon;
while (pg)
{
/* counting how many Polygons are there */
i_pgs++;
pg = pg->Next;
}
if (i_lns + i_pgs == 0)
{
/* empty Input */
return 0;
}
/* testing the Blade type */
pt = blade->FirstPoint;
while (pt)
{
/* counting how many Points are there */
b_pts++;
pt = pt->Next;
}
ln = blade->FirstLinestring;
while (ln)
{
/* counting how many Linestrings are there */
b_lns++;
ln = ln->Next;
}
if (blade->FirstPolygon != NULL)
{
/* Polygon(s) on Blade is forbidden !!!! */
return 0;
}
if (b_pts + b_lns == 0)
{
/* empty Blade */
return 0;
}
if (b_pts >= 1 && b_lns >= 1)
{
/* invalid Blade [point + linestring] */
return 0;
}
/* compatibility check */
if (b_lns >= 1)
{
/* Linestring blade is always valid */
return 1;
}
if (i_lns >= 1 && b_pts >= 1)
{
/* Linestring or MultiLinestring input and Point blade is allowed */
return 1;
}
return 0;
}
static void
set_split_gtype (gaiaGeomCollPtr geom)
{
/* assignign the actual geometry type */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
int pts = 0;
int lns = 0;
int pgs = 0;
pt = geom->FirstPoint;
while (pt)
{
/* counting how many Points are there */
pts++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* counting how many Linestrings are there */
lns++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* counting how many Polygons are there */
pgs++;
pg = pg->Next;
}
if (pts == 1 && lns == 0 && pgs == 0)
{
geom->DeclaredType = GAIA_POINT;
return;
}
if (pts > 1 && lns == 0 && pgs == 0)
{
geom->DeclaredType = GAIA_MULTIPOINT;
return;
}
if (pts == 0 && lns == 1 && pgs == 0)
{
geom->DeclaredType = GAIA_LINESTRING;
return;
}
if (pts == 0 && lns > 1 && pgs == 0)
{
geom->DeclaredType = GAIA_MULTILINESTRING;
return;
}
if (pts == 0 && lns == 0 && pgs == 1)
{
geom->DeclaredType = GAIA_POLYGON;
return;
}
if (pts == 0 && lns == 0 && pgs > 1)
{
geom->DeclaredType = GAIA_MULTIPOLYGON;
return;
}
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
}
static RTGEOM *
toRTGeomLinestring (const RTCTX * ctx, gaiaLinestringPtr ln, int srid)
{
/* converting a GAIA Linestring into a RTGEOM Geometry */
int iv;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
int has_z = 0;
int has_m = 0;
RTPOINTARRAY *pa;
RTPOINT4D point;
if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
pa = ptarray_construct (ctx, has_z, has_m, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
/* copying vertices */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, pa, iv, &point);
}
return (RTGEOM *) rtline_construct (ctx, srid, NULL, pa);
}
static RTGEOM *
toRTGeomPolygon (const RTCTX * ctx, gaiaPolygonPtr pg, int srid)
{
/* converting a GAIA Linestring into a RTGEOM Geometry */
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
int ngeoms;
int has_z = 0;
int has_m = 0;
int close_ring;
gaiaRingPtr rng;
RTPOINTARRAY **ppaa;
RTPOINT4D point;
if (pg->DimensionModel == GAIA_XY_Z || pg->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (pg->DimensionModel == GAIA_XY_M || pg->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
ngeoms = pg->NumInteriors;
ppaa = rtalloc (ctx, sizeof (RTPOINTARRAY *) * (ngeoms + 1));
rng = pg->Exterior;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[0] = ptarray_construct (ctx, has_z, has_m, rng->Points + 1);
else
ppaa[0] = ptarray_construct (ctx, has_z, has_m, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
/* copying vertices - Exterior Ring */
if (pg->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (pg->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (pg->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (pg->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (pg->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (pg->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], rng->Points, &point);
}
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* copying vertices - Interior Rings */
rng = pg->Interiors + ib;
close_ring = check_unclosed_ring (rng);
if (close_ring)
ppaa[1 + ib] =
ptarray_construct (ctx, has_z, has_m, rng->Points + 1);
else
ppaa[1 + ib] = ptarray_construct (ctx, has_z, has_m, rng->Points);
for (iv = 0; iv < rng->Points; iv++)
{
if (pg->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (pg->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (pg->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[1 + ib], iv, &point);
}
if (close_ring)
{
/* making an unclosed ring to be closed */
if (pg->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, 0, &x, &y, &z);
}
else if (pg->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, 0, &x, &y, &m);
}
else if (pg->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, 0, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, 0, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
if (has_m)
point.m = m;
ptarray_set_point4d (ctx, ppaa[0], rng->Points, &point);
}
}
return (RTGEOM *) rtpoly_construct (ctx, srid, NULL, ngeoms + 1, ppaa);
}
static gaiaGeomCollPtr
fromRTGeomLeft (const RTCTX * ctx, gaiaGeomCollPtr gaia, const RTGEOM * rtgeom)
{
/*
/ converting a RTGEOM Geometry into a GAIA Geometry
/ collecting "left side" items
*/
RTGEOM *rtg2 = NULL;
RTCOLLECTION *rtc = NULL;
int ngeoms;
int ig;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
if (rtgeom->type == RTCOLLECTIONTYPE)
{
rtc = (RTCOLLECTION *) rtgeom;
ngeoms = rtc->ngeoms;
for (ig = 0; ig < ngeoms; ig += 2)
{
rtg2 = rtc->geoms[ig];
fromRTGeomIncremental (ctx, gaia, rtg2);
}
}
else
gaia =
fromRTGeom (ctx, rtgeom, gaia->DimensionModel, gaia->DeclaredType);
return gaia;
}
static gaiaGeomCollPtr
fromRTGeomRight (const RTCTX * ctx, gaiaGeomCollPtr gaia, const RTGEOM * rtgeom)
{
/*
/ converting a RTGEOM Geometry into a GAIA Geometry
/ collecting "right side" items
*/
RTGEOM *rtg2 = NULL;
RTCOLLECTION *rtc = NULL;
int ngeoms;
int ig;
if (rtgeom == NULL)
return NULL;
if (rtgeom_is_empty (ctx, rtgeom))
return NULL;
if (rtgeom->type == RTCOLLECTIONTYPE)
{
rtc = (RTCOLLECTION *) rtgeom;
ngeoms = rtc->ngeoms;
for (ig = 1; ig < ngeoms; ig += 2)
{
rtg2 = rtc->geoms[ig];
fromRTGeomIncremental (ctx, gaia, rtg2);
}
}
return gaia;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSplit (const void *p_cache, gaiaGeomCollPtr input, gaiaGeomCollPtr blade)
{
/* wrapping RTGEOM Split */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
RTGEOM *g3;
gaiaGeomCollPtr result = NULL;
if (!check_split_args (input, blade))
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, input);
g2 = toRTGeom (ctx, blade);
g3 = rtgeom_split (ctx, g1, g2);
if (!g3)
{
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
goto done;
}
result = fromRTGeom (ctx, g3, input->DimensionModel, input->DeclaredType);
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
rtgeom_free (ctx, g3);
if (result == NULL)
goto done;
result->Srid = input->Srid;
set_split_gtype (result);
done:
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSplitLeft (const void *p_cache, gaiaGeomCollPtr input,
gaiaGeomCollPtr blade)
{
/* wrapping RTGEOM Split [left half] */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
RTGEOM *g3;
gaiaGeomCollPtr result = NULL;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
if (!check_split_args (input, blade))
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
if (input->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (input->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (input->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
g2 = toRTGeom (ctx, blade);
ln = input->FirstLinestring;
while (ln)
{
/* splitting some Linestring */
g1 = toRTGeomLinestring (ctx, ln, input->Srid);
g3 = rtgeom_split (ctx, g1, g2);
if (g3)
{
result = fromRTGeomLeft (ctx, result, g3);
rtgeom_free (ctx, g3);
}
spatialite_init_geos ();
rtgeom_free (ctx, g1);
ln = ln->Next;
}
pg = input->FirstPolygon;
while (pg)
{
/* splitting some Polygon */
g1 = toRTGeomPolygon (ctx, pg, input->Srid);
g3 = rtgeom_split (ctx, g1, g2);
if (g3)
{
result = fromRTGeomLeft (ctx, result, g3);
rtgeom_free (ctx, g3);
}
spatialite_init_geos ();
rtgeom_free (ctx, g1);
pg = pg->Next;
}
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
if (result->FirstPoint == NULL && result->FirstLinestring == NULL
&& result->FirstPolygon == NULL)
{
gaiaFreeGeomColl (result);
result = NULL;
goto done;
}
result->Srid = input->Srid;
set_split_gtype (result);
done:
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSplitRight (const void *p_cache, gaiaGeomCollPtr input,
gaiaGeomCollPtr blade)
{
/* wrapping RTGEOM Split [right half] */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
RTGEOM *g3;
gaiaGeomCollPtr result = NULL;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
if (!check_split_args (input, blade))
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
if (input->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (input->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (input->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
g2 = toRTGeom (ctx, blade);
ln = input->FirstLinestring;
while (ln)
{
/* splitting some Linestring */
g1 = toRTGeomLinestring (ctx, ln, input->Srid);
g3 = rtgeom_split (ctx, g1, g2);
if (g3)
{
result = fromRTGeomRight (ctx, result, g3);
rtgeom_free (ctx, g3);
}
spatialite_init_geos ();
rtgeom_free (ctx, g1);
ln = ln->Next;
}
pg = input->FirstPolygon;
while (pg)
{
/* splitting some Polygon */
g1 = toRTGeomPolygon (ctx, pg, input->Srid);
g3 = rtgeom_split (ctx, g1, g2);
if (g3)
{
result = fromRTGeomRight (ctx, result, g3);
rtgeom_free (ctx, g3);
}
spatialite_init_geos ();
rtgeom_free (ctx, g1);
pg = pg->Next;
}
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
if (result->FirstPoint == NULL && result->FirstLinestring == NULL
&& result->FirstPolygon == NULL)
{
gaiaFreeGeomColl (result);
result = NULL;
goto done;
}
result->Srid = input->Srid;
set_split_gtype (result);
done:
return result;
}
GAIAGEO_DECLARE int
gaiaAzimuth (const void *p_cache, double xa, double ya, double xb, double yb,
double *azimuth)
{
/* wrapping RTGEOM Azimuth */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTPOINT2D pt1;
RTPOINT2D pt2;
double az;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
pt1.x = xa;
pt1.y = ya;
pt2.x = xb;
pt2.y = yb;
if (!azimuth_pt_pt (ctx, &pt1, &pt2, &az))
ret = 0;
*azimuth = az;
return ret;
}
GAIAGEO_DECLARE int
gaiaEllipsoidAzimuth (const void *p_cache, double xa, double ya, double xb,
double yb, double a, double b, double *azimuth)
{
/* wrapping RTGEOM AzimuthSpheroid */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTPOINT *pt1;
RTPOINT *pt2;
SPHEROID ellips;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
pt1 = rtpoint_make2d (ctx, 0, xa, ya);
pt2 = rtpoint_make2d (ctx, 0, xb, yb);
spheroid_init (ctx, &ellips, a, b);
*azimuth = rtgeom_azumith_spheroid (ctx, pt1, pt2, &ellips);
rtpoint_free (ctx, pt1);
rtpoint_free (ctx, pt2);
return ret;
}
GAIAGEO_DECLARE int
gaiaProjectedPoint (const void *p_cache, double x1, double y1, double a,
double b, double distance, double azimuth, double *x2,
double *y2)
{
/* wrapping RTGEOM Project */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTPOINT *pt1;
RTPOINT *pt2;
SPHEROID ellips;
int ret = 0;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
pt1 = rtpoint_make2d (ctx, 0, x1, y1);
spheroid_init (ctx, &ellips, a, b);
pt2 = rtgeom_project_spheroid (ctx, pt1, &ellips, distance, azimuth);
rtpoint_free (ctx, pt1);
if (pt2 != NULL)
{
*x2 = rtpoint_get_x (ctx, pt2);
*y2 = rtpoint_get_y (ctx, pt2);
rtpoint_free (ctx, pt2);
ret = 1;
}
return ret;
}
GAIAGEO_DECLARE int
gaiaGeodesicArea (const void *p_cache, gaiaGeomCollPtr geom, double a, double b,
int use_ellipsoid, double *area)
{
/* wrapping RTGEOM AreaSphere and AreaSpheroid */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
SPHEROID ellips;
RTGBOX gbox;
double tolerance = 1e-12;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
g = toRTGeom (ctx, geom);
spheroid_init (ctx, &ellips, a, b);
if (g == NULL)
{
ret = 0;
goto done;
}
rtgeom_calculate_gbox_geodetic (ctx, g, &gbox);
if (use_ellipsoid)
{
/* testing for "forbidden" calculations on the ellipsoid */
if ((gbox.zmax + tolerance) >= 1.0 || (gbox.zmin - tolerance) <= -1.0)
use_ellipsoid = 0; /* can't circle the poles */
if (gbox.zmax > 0.0 && gbox.zmin < 0.0)
use_ellipsoid = 0; /* can't cross the equator */
}
if (use_ellipsoid)
*area = rtgeom_area_spheroid (ctx, g, &ellips);
else
*area = rtgeom_area_sphere (ctx, g, &ellips);
rtgeom_free (ctx, g);
done:
return ret;
}
GAIAGEO_DECLARE char *
gaiaGeoHash (const void *p_cache, gaiaGeomCollPtr geom, int precision)
{
/* wrapping RTGEOM GeoHash */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
char *result;
char *geo_hash = NULL;
int len;
if (!geom)
return NULL;
gaiaMbrGeometry (geom);
if (geom->MinX < -180.0 || geom->MaxX > 180.0 || geom->MinY < -90.0
|| geom->MaxY > 90.0)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g = toRTGeom (ctx, geom);
result = rtgeom_geohash (ctx, g, precision);
rtgeom_free (ctx, g);
if (result == NULL)
goto done;
len = strlen (result);
if (len == 0)
{
rtfree (ctx, result);
goto done;
}
geo_hash = malloc (len + 1);
strcpy (geo_hash, result);
rtfree (ctx, result);
done:
return geo_hash;
}
GAIAGEO_DECLARE char *
gaiaAsX3D (const void *p_cache, gaiaGeomCollPtr geom, const char *srs,
int precision, int options, const char *defid)
{
/* wrapping RTGEOM AsX3D */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
char *result;
char *x3d = NULL;
int len;
if (!geom)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
gaiaMbrGeometry (geom);
g = toRTGeom (ctx, geom);
result = rtgeom_to_x3d3 (ctx, g, (char *) srs, precision, options, defid);
rtgeom_free (ctx, g);
if (result == NULL)
goto done;
len = strlen (result);
if (len == 0)
{
rtfree (ctx, result);
goto done;
}
x3d = malloc (len + 1);
strcpy (x3d, result);
rtfree (ctx, result);
done:
return x3d;
}
GAIAGEO_DECLARE int
gaia3DDistance (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist)
{
/* wrapping RTGEOM mindistance3d */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
double d;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
g1 = toRTGeom (ctx, geom1);
g2 = toRTGeom (ctx, geom2);
d = rtgeom_mindistance3d (ctx, g1, g2);
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
*dist = d;
return ret;
}
GAIAGEO_DECLARE int
gaiaMaxDistance (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist)
{
/* wrapping RTGEOM maxdistance2d */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
double d;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
g1 = toRTGeom (ctx, geom1);
g2 = toRTGeom (ctx, geom2);
d = rtgeom_maxdistance2d (ctx, g1, g2);
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
*dist = d;
return ret;
}
GAIAGEO_DECLARE int
gaia3DMaxDistance (const void *p_cache, gaiaGeomCollPtr geom1,
gaiaGeomCollPtr geom2, double *dist)
{
/* wrapping RTGEOM maxdistance2d */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
double d;
int ret = 1;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
g1 = toRTGeom (ctx, geom1);
g2 = toRTGeom (ctx, geom2);
d = rtgeom_maxdistance3d (ctx, g1, g2);
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
*dist = d;
return ret;
}
static RTLINE *
linestring2rtline (const RTCTX * ctx, gaiaLinestringPtr ln, int srid)
{
/* converting a Linestring into an RTLINE */
RTPOINTARRAY *pa;
RTPOINT4D point;
int iv;
double x;
double y;
double z;
double m;
int has_z = 0;
if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
pa = ptarray_construct (ctx, has_z, 0, ln->Points);
for (iv = 0; iv < ln->Points; iv++)
{
/* copying vertices */
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
point.x = x;
point.y = y;
if (has_z)
point.z = z;
else
point.z = 0.0;
point.m = 0.0;
ptarray_set_point4d (ctx, pa, iv, &point);
}
return rtline_construct (ctx, srid, NULL, pa);
}
GAIAGEO_DECLARE int
gaia3dLength (const void *p_cache, gaiaGeomCollPtr geom, double *length)
{
/* wrapping RTGEOM rtline_length */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTLINE *line;
gaiaLinestringPtr ln;
double l = 0.0;
int ret = 0;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
ln = geom->FirstLinestring;
while (ln != NULL)
{
ret = 1;
line = linestring2rtline (ctx, ln, geom->Srid);
l += rtgeom_length (ctx, (RTGEOM *) line);
rtline_free (ctx, line);
ln = ln->Next;
}
*length = l;
return ret;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaNodeLines (const void *p_cache, gaiaGeomCollPtr geom)
{
/* wrapping RTGEOM rtgeom_node */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTGEOM *g2;
gaiaGeomCollPtr result = NULL;
if (!geom)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, geom);
g2 = rtgeom_node (ctx, g1);
if (!g2)
{
rtgeom_free (ctx, g1);
goto done;
}
result = fromRTGeom (ctx, g2, geom->DimensionModel, geom->DeclaredType);
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtgeom_free (ctx, g2);
if (result == NULL)
goto done;
result->Srid = geom->Srid;
done:
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSubdivide (const void *p_cache, gaiaGeomCollPtr geom, int max_vertices)
{
/* wrapping RTGEOM rtgeom_node */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g1;
RTCOLLECTION *g2;
gaiaGeomCollPtr result = NULL;
int i;
if (!geom)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g1 = toRTGeom (ctx, geom);
g2 = rtgeom_subdivide (ctx, g1, max_vertices);
if (!g2)
{
rtgeom_free (ctx, g1);
goto done;
}
/* building the subdivided geometry to be returned */
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
for (i = 0; i < g2->ngeoms; i++)
{
RTGEOM *g3 = *(g2->geoms + i);
fromRTGeomIncremental (ctx, result, g3);
}
spatialite_init_geos ();
rtgeom_free (ctx, g1);
rtcollection_free (ctx, g2);
if (result == NULL)
goto done;
result->Srid = geom->Srid;
done:
return result;
}
GAIAGEO_DECLARE int
gaiaToTWKB (const void *p_cache, gaiaGeomCollPtr geom,
unsigned char precision_xy, unsigned char precision_z,
unsigned char precision_m, int with_size, int with_bbox,
unsigned char **twkb, int *size_twkb)
{
/* wrapping RTGEOM rtgeom_to_twkb */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
unsigned char variant = 0;
RTGEOM *g;
unsigned char *p_twkb;
size_t twkb_size;
*twkb = NULL;
*size_twkb = 0;
if (!geom)
return 0;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
if (with_size)
variant |= TWKB_SIZE;
if (with_bbox)
variant |= TWKB_BBOX;
g = toRTGeom (ctx, geom);
p_twkb =
rtgeom_to_twkb (ctx, g, variant, precision_xy, precision_z, precision_m,
&twkb_size);
rtgeom_free (ctx, g);
if (p_twkb == NULL)
return 0;
*twkb = p_twkb;
*size_twkb = twkb_size;
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromTWKB (const void *p_cache, const unsigned char *twkb, int twkb_size,
int srid)
{
/* wrapping RTGEOM rtgeom_from_twkb */
const RTCTX *ctx = NULL;
int dims = GAIA_XY_Z_M;
int type = GAIA_GEOMETRYCOLLECTION;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
gaiaGeomCollPtr result;
if (twkb == NULL)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g = rtgeom_from_twkb (ctx, (unsigned char *) twkb, twkb_size, 0);
if (g == NULL)
return NULL;
if ((*(twkb + 0) & 0x01) == 0x01)
type = GAIA_POINT;
if ((*(twkb + 0) & 0x02) == 0x02)
type = GAIA_LINESTRING;
if ((*(twkb + 0) & 0x03) == 0x03)
type = GAIA_POLYGON;
if ((*(twkb + 0) & 0x04) == 0x04)
type = GAIA_MULTIPOINT;
if ((*(twkb + 0) & 0x05) == 0x05)
type = GAIA_MULTILINESTRING;
if ((*(twkb + 0) & 0x06) == 0x06)
type = GAIA_MULTIPOLYGON;
if ((*(twkb + 0) & 0x07) == 0x07)
type = GAIA_GEOMETRYCOLLECTION;
if ((*(twkb + 1) & 0x08) == 0x08)
{
if ((*(twkb + 2) & 0x01) == 0x01)
dims = GAIA_XY_Z;
if ((*(twkb + 2) & 0x02) == 0x02)
dims = GAIA_XY_M;
if ((*(twkb + 2) & 0x03) == 0x03)
dims = GAIA_XY_Z_M;
}
else
dims = GAIA_XY;
result = fromRTGeom (ctx, g, dims, type);
spatialite_init_geos ();
rtgeom_free (ctx, g);
if (result != NULL)
result->Srid = srid;
return result;
}
GAIAGEO_DECLARE int
gaiaAsEncodedPolyLine (const void *p_cache, gaiaGeomCollPtr geom,
unsigned char precision, char **encoded, int *len)
{
/* wrapping RTGEOM rtline_to_encoded_polyline */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
char *p_encoded;
*encoded = NULL;
*len = 0;
if (!geom)
return 0;
if (cache == NULL)
return 0;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return 0;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return 0;
g = toRTGeom (ctx, geom);
p_encoded = rtgeom_to_encoded_polyline (ctx, g, precision);
rtgeom_free (ctx, g);
if (p_encoded == NULL)
return 0;
*encoded = p_encoded;
*len = strlen (p_encoded);
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaLineFromEncodedPolyline (const void *p_cache, const char *encoded,
unsigned char precision)
{
/* wrapping RTGEOM rtline_from_encoded_polyline */
const RTCTX *ctx = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
RTGEOM *g;
gaiaGeomCollPtr result;
int dims = GAIA_XY;
int type = GAIA_LINESTRING;
if (encoded == NULL)
return NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
ctx = cache->RTTOPO_handle;
if (ctx == NULL)
return NULL;
g = rtgeom_from_encoded_polyline (ctx, encoded, precision);
if (g == NULL)
return NULL;
result = fromRTGeom (ctx, g, dims, type);
spatialite_init_geos ();
rtgeom_free (ctx, g);
if (result != NULL)
result->Srid = 4326;
return result;
}
static RTGEOM *
rtgeom_from_encoded_polyline (const RTCTX * ctx, const char *encodedpolyline,
int precision)
{
/*
* RTTOPO lacks an implementation of rtgeom_from_encoded_polyline
*
* this simply is a rearranged version of the original code available
* on LWGOEM lwin_encoded_polyline.c
*
* Copyright 2014 Kashif Rasul
*
* the original code was released under the terms of the GNU General
* Public License as published by the Free Software Foundation, either
* version 2 of the License, or (at your option) any later version.
*/
RTGEOM *geom = NULL;
RTPOINTARRAY *pa = NULL;
int length = strlen (encodedpolyline);
int idx = 0;
double scale = pow (10, precision);
float latitude = 0.0f;
float longitude = 0.0f;
pa = ptarray_construct_empty (ctx, RT_FALSE, RT_FALSE, 1);
while (idx < length)
{
RTPOINT4D pt;
char byte = 0;
int res = 0;
char shift = 0;
do
{
byte = encodedpolyline[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
}
while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do
{
byte = encodedpolyline[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
}
while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
pt.x = longitude / scale;
pt.y = latitude / scale;
pt.m = pt.z = 0.0;
ptarray_append_point (ctx, pa, &pt, RT_FALSE);
}
geom = (RTGEOM *) rtline_construct (ctx, 4326, NULL, pa);
rtgeom_add_bbox (ctx, geom);
return geom;
}
#endif /* end enabling RTTOPO support */
libspatialite-5.1.0/src/gaiageo/gg_extras.c 0000644 0001750 0001750 00000110421 14463127014 015577 0000000 0000000 /*
gg_extras.c -- Gaia extra functions support
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2012-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#if defined(_MSC_VER) && _MSC_VER < 1800
/*
/ only when using an obsolete MSVC (< 2013)
/ we need to define an internal replacement
/ implementig C99 rint()
*/
static double
rint (double x)
{
return floor (x + 0.5);
}
#endif
#endif
static void
auxGridSnapPoint (int dimension_model, gaiaPointPtr pt, gaiaGeomCollPtr result,
double origin_x, double origin_y, double origin_z,
double origin_m, double size_x, double size_y, double size_z,
double size_m)
{
/* snapping a Point to a regular Grid */
double x = pt->X;
double y = pt->Y;
double z = 0.0;
double m = 0.0;
int has_z = 0;
int has_m = 0;
gaiaPointPtr ptx;
if (pt == NULL || result == NULL)
return;
if (dimension_model == GAIA_XY_Z || dimension_model == GAIA_XY_Z_M)
has_z = 1;
if (dimension_model == GAIA_XY_M || dimension_model == GAIA_XY_Z_M)
has_m = 1;
if (has_z)
z = pt->Z;
if (has_m)
m = pt->M;
/* snapping coords to the given grid */
if (size_x > 0.0)
x = rint ((x - origin_x) / size_x) * size_x + origin_x;
if (size_y > 0.0)
y = rint ((y - origin_y) / size_y) * size_y + origin_y;
if (has_z && size_z > 0.0)
z = rint ((z - origin_z) / size_z) * size_z + origin_z;
if (has_m && size_m > 0.0)
m = rint ((m - origin_m) / size_m) * size_m + origin_m;
ptx = result->FirstPoint;
while (ptx)
{
/* checking if already defined */
if (has_z && has_m)
{
if (ptx->X == x && ptx->Y == y && ptx->Z == z && ptx->M == m)
return;
}
else if (has_z)
{
if (ptx->X == x && ptx->Y == y && ptx->Z == z)
return;
}
else if (has_m)
{
if (ptx->X == x && ptx->Y == y && ptx->M == m)
return;
}
else
{
if (ptx->X == x && ptx->Y == y)
return;
}
ptx = ptx->Next;
}
/* inserting the snapped Point into the result Geometry */
if (has_z && has_m)
gaiaAddPointToGeomCollXYZM (result, x, y, z, m);
else if (has_z)
gaiaAddPointToGeomCollXYZ (result, x, y, z);
else if (has_m)
gaiaAddPointToGeomCollXYM (result, x, y, m);
else
gaiaAddPointToGeomColl (result, x, y);
}
static void
auxGridSnapLinestring (gaiaLinestringPtr ln, gaiaGeomCollPtr result,
double origin_x, double origin_y, double origin_z,
double origin_m, double size_x, double size_y,
double size_z, double size_m)
{
/* snapping a Linestring to a regular Grid */
double x;
double y;
double z;
double m;
int has_z = 0;
int has_m = 0;
int iv;
gaiaDynamicLinePtr dyn;
gaiaPointPtr pt;
gaiaLinestringPtr lnx;
int count = 0;
if (ln == NULL || result == NULL)
return;
if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
dyn = gaiaAllocDynamicLine ();
for (iv = 0; iv < ln->Points; iv++)
{
/* snapping each Vertex to the given grid */
int to_be_inserted = 0;
z = 0.0;
m = 0.0;
if (has_z && has_m)
{
gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
}
else if (has_z)
{
gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
}
else if (has_m)
{
gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (ln->Coords, iv, &x, &y);
}
/* snapping coords to the given grid */
if (size_x > 0.0)
x = rint ((x - origin_x) / size_x) * size_x + origin_x;
if (size_y > 0.0)
y = rint ((y - origin_y) / size_y) * size_y + origin_y;
if (has_z && size_z > 0.0)
z = rint ((z - origin_z) / size_z) * size_z + origin_z;
if (has_m && size_m > 0.0)
m = rint ((m - origin_m) / size_m) * size_m + origin_m;
if (dyn->Last == NULL)
to_be_inserted = 1;
else
{
/* skipping repeated points */
pt = dyn->Last;
if (has_z && has_m)
{
if (pt->X == x && pt->Y == y && pt->Z == z && pt->M == m)
;
else
to_be_inserted = 1;
}
else if (has_z)
{
if (pt->X == x && pt->Y == y && pt->Z == z)
;
else
to_be_inserted = 1;
}
else if (has_m)
{
if (pt->X == x && pt->Y == y && pt->M == m)
;
else
to_be_inserted = 1;
}
else
{
if (pt->X == x && pt->Y == y)
;
else
to_be_inserted = 1;
}
}
if (to_be_inserted)
{
if (has_z && has_m)
gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m);
else if (has_z)
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
else if (has_m)
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
else
gaiaAppendPointToDynamicLine (dyn, x, y);
}
}
/* checking for validity */
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
count++;
pt = pt->Next;
}
if (count < 2)
{
/* skipping any collapsed line */
gaiaFreeDynamicLine (dyn);
return;
}
/* inserting into the result Geometry */
lnx = gaiaAddLinestringToGeomColl (result, count);
iv = 0;
pt = dyn->First;
while (pt)
{
/* copying points */
if (lnx->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (lnx->Coords, iv, pt->X, pt->Y, pt->Z);
}
else if (lnx->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (lnx->Coords, iv, pt->X, pt->Y, pt->M);
}
else if (lnx->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (lnx->Coords, iv, pt->X, pt->Y, pt->Z, pt->M);
}
else
{
gaiaSetPoint (lnx->Coords, iv, pt->X, pt->Y);
}
iv++;
pt = pt->Next;
}
gaiaFreeDynamicLine (dyn);
}
static gaiaDynamicLinePtr
auxGridSnapRing (gaiaRingPtr rng, double origin_x, double origin_y,
double origin_z, double origin_m, double size_x, double size_y,
double size_z, double size_m)
{
/* snapping a Ring to a regular Grid */
double x;
double y;
double z;
double m;
int has_z = 0;
int has_m = 0;
int iv;
gaiaDynamicLinePtr dyn;
gaiaPointPtr pt0;
gaiaPointPtr pt;
int count = 0;
if (rng == NULL)
return NULL;
if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M)
has_z = 1;
if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M)
has_m = 1;
dyn = gaiaAllocDynamicLine ();
for (iv = 0; iv < rng->Points; iv++)
{
/* snapping each Vertex to the given grid */
int to_be_inserted = 0;
z = 0.0;
m = 0.0;
if (has_z && has_m)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else if (has_z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (has_m)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
/* snapping coords to the given grid */
if (size_x > 0.0)
x = rint ((x - origin_x) / size_x) * size_x + origin_x;
if (size_y > 0.0)
y = rint ((y - origin_y) / size_y) * size_y + origin_y;
if (has_z && size_z > 0.0)
z = rint ((z - origin_z) / size_z) * size_z + origin_z;
if (has_m && size_m > 0.0)
m = rint ((m - origin_m) / size_m) * size_m + origin_m;
if (dyn->Last == NULL)
to_be_inserted = 1;
else
{
/* skipping repeated points */
pt = dyn->Last;
if (has_z && has_m)
{
if (pt->X == x && pt->Y == y && pt->Z == z && pt->M == m)
;
else
to_be_inserted = 1;
}
else if (has_z)
{
if (pt->X == x && pt->Y == y && pt->Z == z)
;
else
to_be_inserted = 1;
}
else if (has_m)
{
if (pt->X == x && pt->Y == y && pt->M == m)
;
else
to_be_inserted = 1;
}
else
{
if (pt->X == x && pt->Y == y)
;
else
to_be_inserted = 1;
}
}
if (to_be_inserted)
{
if (has_z && has_m)
gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m);
else if (has_z)
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
else if (has_m)
gaiaAppendPointMToDynamicLine (dyn, x, y, m);
else
gaiaAppendPointToDynamicLine (dyn, x, y);
}
}
/* ensuring for Ring closure */
pt0 = dyn->First;
pt = dyn->Last;
if (has_z && has_m)
{
if (pt0->X == pt->X && pt0->Y == pt->Y && pt0->Z == pt->Z
&& pt0->M == pt->M)
;
else
gaiaAppendPointZMToDynamicLine (dyn, pt->X, pt->Y, pt->Z, pt->M);
}
else if (has_z)
{
if (pt0->X == pt->X && pt0->Y == pt->Y && pt0->Z == pt->Z)
;
else
gaiaAppendPointZToDynamicLine (dyn, pt->X, pt->Y, pt->Z);
}
else if (has_m)
{
if (pt0->X == pt->X && pt0->Y == pt->Y && pt0->M == pt->M)
;
else
gaiaAppendPointMToDynamicLine (dyn, pt->X, pt->Y, pt->M);
}
else
{
if (pt0->X == pt->X && pt0->Y == pt->Y)
;
else
gaiaAppendPointToDynamicLine (dyn, pt->X, pt->Y);
}
/* checking for validity */
pt = dyn->First;
while (pt)
{
/* counting how many points are there */
count++;
pt = pt->Next;
}
if (count < 4)
{
/* skipping any collapsed ring */
gaiaFreeDynamicLine (dyn);
return NULL;
}
return dyn;
}
static void
auxGridSnapPolygon (gaiaPolygonPtr pg, gaiaGeomCollPtr result, double origin_x,
double origin_y, double origin_z, double origin_m,
double size_x, double size_y, double size_z, double size_m)
{
/* snapping a Polygon to a regular Grid */
int ib;
int holes = 0;
int count;
int next_hole = 0;
int iv;
gaiaRingPtr rng;
gaiaPolygonPtr pgx;
gaiaPointPtr pt;
gaiaDynamicLinePtr rng_ext;
gaiaDynamicLinePtr dyn;
gaiaDynamicLinePtr *rng_ints = NULL;
if (pg == NULL || result == NULL)
return;
/* snapping the Exterior Ring */
rng = pg->Exterior;
rng_ext =
auxGridSnapRing (rng, origin_x, origin_y, origin_z, origin_m, size_x,
size_y, size_z, size_m);
if (rng_ext == NULL) /* skipping any collaped Polygon */
return;
if (pg->NumInteriors)
{
/* snapping any Interior Ring */
rng_ints = malloc (sizeof (gaiaRingPtr *) * pg->NumInteriors);
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
*(rng_ints + ib) =
auxGridSnapRing (rng, origin_x, origin_y, origin_z,
origin_m, size_x, size_y, size_z, size_m);
if (*(rng_ints + ib) != NULL)
holes++;
}
}
/* inserting into the result Geometry */
pt = rng_ext->First;
count = 0;
while (pt)
{
/* counting how many points are in the Exterior Ring */
count++;
pt = pt->Next;
}
pgx = gaiaAddPolygonToGeomColl (result, count, holes);
rng = pgx->Exterior;
iv = 0;
pt = rng_ext->First;
while (pt)
{
/* copying Exterior Ring points */
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, pt->X, pt->Y, pt->Z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, pt->X, pt->Y, pt->M);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, pt->X, pt->Y, pt->Z, pt->M);
}
else
{
gaiaSetPoint (rng->Coords, iv, pt->X, pt->Y);
}
iv++;
pt = pt->Next;
}
if (holes > 0)
{
/* setting up any not-collapsed Hole */
for (ib = 0; ib < pg->NumInteriors; ib++)
{
if (*(rng_ints + ib) == NULL)
continue;
dyn = *(rng_ints + ib);
pt = dyn->First;
count = 0;
while (pt)
{
/* counting how many points are in the Exterior Ring */
count++;
pt = pt->Next;
}
rng = gaiaAddInteriorRing (pgx, next_hole++, count);
iv = 0;
pt = dyn->First;
while (pt)
{
/* copying Interior Ring points */
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (rng->Coords, iv, pt->X, pt->Y,
pt->Z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (rng->Coords, iv, pt->X, pt->Y,
pt->M);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (rng->Coords, iv, pt->X, pt->Y,
pt->Z, pt->M);
}
else
{
gaiaSetPoint (rng->Coords, iv, pt->X, pt->Y);
}
iv++;
pt = pt->Next;
}
}
}
/* memory clean-up */
gaiaFreeDynamicLine (rng_ext);
if (rng_ints)
{
for (ib = 0; ib < pg->NumInteriors; ib++)
{
dyn = *(rng_ints + ib);
if (dyn)
gaiaFreeDynamicLine (dyn);
}
free (rng_ints);
}
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSnapToGrid (gaiaGeomCollPtr geom, double origin_x, double origin_y,
double origin_z, double origin_m, double size_x, double size_y,
double size_z, double size_m)
{
/* creating a Geometry snapped to a regular Grid */
gaiaGeomCollPtr result;
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
if (!geom)
return NULL;
/* creating the output Geometry */
if (geom->DimensionModel == GAIA_XY_Z)
result = gaiaAllocGeomCollXYZ ();
else if (geom->DimensionModel == GAIA_XY_M)
result = gaiaAllocGeomCollXYM ();
else if (geom->DimensionModel == GAIA_XY_Z_M)
result = gaiaAllocGeomCollXYZM ();
else
result = gaiaAllocGeomColl ();
/* snapping elementary Geometries to the given Grid */
pt = geom->FirstPoint;
while (pt)
{
/* snapping POINTs */
auxGridSnapPoint (geom->DimensionModel, pt, result, origin_x,
origin_y, origin_z, origin_m, size_x, size_y,
size_z, size_m);
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* snapping LINESTRINGs */
auxGridSnapLinestring (ln, result, origin_x, origin_y, origin_z,
origin_m, size_x, size_y, size_z, size_m);
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* snapping POLYGONs */
auxGridSnapPolygon (pg, result, origin_x, origin_y, origin_z,
origin_m, size_x, size_y, size_z, size_m);
pg = pg->Next;
}
/* validating the output Geometry */
pt = result->FirstPoint;
while (pt)
{
/* counting how many POINTs are there */
pts++;
pt = pt->Next;
}
ln = result->FirstLinestring;
while (ln)
{
/* counting how many LINESTRINGs are there */
lns++;
ln = ln->Next;
}
pg = result->FirstPolygon;
while (pg)
{
/* counting how many POLYGONs are there */
pgs++;
pg = pg->Next;
}
if (pts == 0 && lns == 0 && pgs == 0)
{
/* empty result */
gaiaFreeGeomColl (result);
return NULL;
}
/* final adjustment */
result->Srid = geom->Srid;
if (pts == 1 && lns == 0 && pgs == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else if (geom->DeclaredType == GAIA_MULTIPOINT)
result->DeclaredType = GAIA_MULTIPOINT;
else
result->DeclaredType = GAIA_POINT;
}
else if (pts == 0 && lns == 1 && pgs == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else if (geom->DeclaredType == GAIA_MULTILINESTRING)
result->DeclaredType = GAIA_MULTILINESTRING;
else
result->DeclaredType = GAIA_LINESTRING;
}
else if (pts == 0 && lns == 0 && pgs == 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else if (geom->DeclaredType == GAIA_MULTIPOLYGON)
result->DeclaredType = GAIA_MULTIPOLYGON;
else
result->DeclaredType = GAIA_POLYGON;
}
else if (pts > 1 && lns == 0 && pgs == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
result->DeclaredType = GAIA_MULTIPOINT;
}
else if (pts == 0 && lns > 1 && pgs == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
result->DeclaredType = GAIA_MULTILINESTRING;
}
else if (pts == 0 && lns == 0 && pgs > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
else
result->DeclaredType = GAIA_MULTIPOLYGON;
}
else
result->DeclaredType = GAIA_GEOMETRYCOLLECTION;
return result;
}
#ifndef OMIT_GEOS /* only if GEOS is enabled */
static void
get_grid_bbox (gaiaGeomCollPtr geom, double *min_x, double *min_y,
double *max_x, double *max_y)
{
/* extracting the BBOX representing the input geometry */
gaiaMbrGeometry (geom);
*min_x = geom->MinX;
*min_y = geom->MinY;
*max_x = geom->MaxX;
*max_y = geom->MaxY;
}
static void
get_grid_base (double min_x, double min_y, double origin_x, double origin_y,
double size, double *base_x, double *base_y)
{
/* determining the grid base-point [MinX/MinY] */
double x = rint ((min_x - origin_x) / size) * size + origin_x;
double y = rint ((min_y - origin_y) / size) * size + origin_y;
if (x > min_x)
*base_x = x - size;
else
*base_x = x;
if (y > min_y)
*base_y = y - size;
else
*base_y = y;
}
static gaiaGeomCollPtr
gaiaSquareGridCommon (const void *p_cache, gaiaGeomCollPtr geom,
double origin_x, double origin_y, double size, int mode)
{
/* creating a regular grid [Square cells] */
double min_x;
double min_y;
double max_x;
double max_y;
double base_x;
double base_y;
double x1;
double y1;
double x2;
double y2;
double x3;
double y3;
double x4;
double y4;
int count = 0;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaLinestringPtr ln;
gaiaGeomCollPtr result = NULL;
gaiaGeomCollPtr item = NULL;
int ret;
if (size <= 0.0)
return NULL;
result = gaiaAllocGeomColl ();
result->Srid = geom->Srid;
get_grid_bbox (geom, &min_x, &min_y, &max_x, &max_y);
get_grid_base (min_x, min_y, origin_x, origin_y, size, &base_x, &base_y);
while (base_y < max_y)
{
/* looping on grid rows */
x1 = base_x;
y1 = base_y;
x2 = x1 + size;
y2 = y1;
x3 = x2;
y3 = y1 + size;
x4 = x1;
y4 = y3;
while (x1 < max_x)
{
/* looping on grid columns */
item = gaiaAllocGeomColl ();
pg = gaiaAddPolygonToGeomColl (item, 5, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x4, y4);
gaiaSetPoint (rng->Coords, 4, x1, y1);
gaiaMbrGeometry (item);
if (p_cache != NULL)
ret = gaiaGeomCollIntersects_r (p_cache, geom, item);
else
ret = gaiaGeomCollIntersects (geom, item);
if (ret == 1)
{
/* ok, inserting a valid cell */
count++;
if (mode > 0)
{
/* multilinestring */
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x1, y1);
gaiaSetPoint (ln->Coords, 1, x2, y2);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x2, y2);
gaiaSetPoint (ln->Coords, 1, x3, y3);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x3, y3);
gaiaSetPoint (ln->Coords, 1, x4, y4);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x4, y4);
gaiaSetPoint (ln->Coords, 1, x1, y1);
}
else if (mode < 0)
{
/* multipoint */
gaiaAddPointToGeomColl (result, x1, y1);
gaiaAddPointToGeomColl (result, x2, y2);
gaiaAddPointToGeomColl (result, x3, y3);
gaiaAddPointToGeomColl (result, x4, y4);
}
else
{
/* polygon */
pg = gaiaAddPolygonToGeomColl (result, 5, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x4, y4);
gaiaSetPoint (rng->Coords, 4, x1, y1);
}
}
gaiaFreeGeomColl (item);
x1 += size;
x2 += size;
x3 += size;
x4 += size;
}
base_y += size;
}
/* final check */
if (!count)
{
/* empty grid */
gaiaFreeGeomColl (result);
return NULL;
}
if (mode == 0)
{
result->DeclaredType = GAIA_MULTIPOLYGON;
return result;
}
item = result;
if (p_cache != NULL)
result = gaiaUnaryUnion_r (p_cache, item);
else
result = gaiaUnaryUnion (item);
gaiaFreeGeomColl (item);
result->Srid = geom->Srid;
if (mode < 0)
result->DeclaredType = GAIA_MULTIPOINT;
else
result->DeclaredType = GAIA_MULTILINESTRING;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSquareGrid (gaiaGeomCollPtr geom, double origin_x, double origin_y,
double size, int mode)
{
return gaiaSquareGridCommon (NULL, geom, origin_x, origin_y, size, mode);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaSquareGrid_r (const void *p_cache, gaiaGeomCollPtr geom, double origin_x,
double origin_y, double size, int mode)
{
return gaiaSquareGridCommon (p_cache, geom, origin_x, origin_y, size, mode);
}
static void
get_trigrid_base (double min_x, double min_y, double origin_x, double origin_y,
double shift_h_odd, double shift_h_even, double shift_v,
int *odd_even, double *base_x, double *base_y)
{
/* determining the grid base-point [MinX/MinY] for a Triangular Grid */
double bx = origin_x;
double by = origin_y;
while (1)
{
/* looping on grid rows */
if (min_y < origin_y)
{
/* going southward */
if (by > min_y)
goto next_scanline;
if (*odd_even)
bx = origin_x - shift_h_odd;
else
bx = origin_x;
}
else
{
/* going northward */
if (by < min_y)
goto next_scanline;
if (*odd_even)
bx = origin_x - shift_h_odd;
else
bx = origin_x;
}
while (1)
{
/* looping on grid columns */
if (min_x < origin_x)
{
/* going eastward */
if (bx - shift_h_even - shift_h_odd < min_x)
{
*base_x = bx;
*base_y = by;
return;
}
bx -= shift_h_even;
}
else
{
/* going westward */
if (bx + shift_h_even > min_x
|| bx + shift_h_even + shift_h_odd > min_x)
{
*base_x = bx;
*base_y = by;
return;
}
bx += shift_h_even;
}
}
next_scanline:
if (min_y < origin_y)
by -= shift_v;
else
by += shift_v;
if (*odd_even)
*odd_even = 0;
else
*odd_even = 1;
}
}
static gaiaGeomCollPtr
gaiaTriangularGridCommon (const void *p_cache, gaiaGeomCollPtr geom,
double origin_x, double origin_y, double size,
int mode)
{
/* creating a regular grid [Triangular cells] */
double min_x;
double min_y;
double max_x;
double max_y;
double base_x;
double base_y;
double x1;
double y1;
double x2;
double y2;
double x3;
double y3;
double x4;
double y4;
double shift_h_odd;
double shift_h_even;
double shift_v;
int count = 0;
int odd_even = 0;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaLinestringPtr ln;
gaiaGeomCollPtr result = NULL;
gaiaGeomCollPtr item = NULL;
int ret;
if (size <= 0.0)
return NULL;
shift_h_odd = size / 2.0;
shift_h_even = size;
shift_v = size * sin (3.14159265358979323846 / 3.0);
result = gaiaAllocGeomColl ();
result->Srid = geom->Srid;
get_grid_bbox (geom, &min_x, &min_y, &max_x, &max_y);
get_trigrid_base (min_x, min_y, origin_x, origin_y, shift_h_odd,
shift_h_even, shift_v, &odd_even, &base_x, &base_y);
base_x -= base_x;
base_y -= shift_v;
while (base_y < max_y)
{
/* looping on grid rows */
if (odd_even)
x1 = base_x - shift_h_odd;
else
x1 = base_x;
y1 = base_y;
x2 = x1 + shift_h_even;
y2 = y1;
x3 = x1 + shift_h_odd;
y3 = y1 + shift_v;
x4 = x3 + shift_h_even;
y4 = y3;
while (x1 < max_x)
{
/* looping on grid columns */
item = gaiaAllocGeomColl ();
pg = gaiaAddPolygonToGeomColl (item, 4, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x1, y1);
gaiaMbrGeometry (item);
if (p_cache != NULL)
ret = gaiaGeomCollIntersects_r (p_cache, geom, item);
else
ret = gaiaGeomCollIntersects (geom, item);
if (ret == 1)
{
/* ok, inserting a valid cell [pointing upside] */
count++;
if (mode > 0)
{
/* multilinestring */
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x1, y1);
gaiaSetPoint (ln->Coords, 1, x2, y2);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x2, y2);
gaiaSetPoint (ln->Coords, 1, x3, y3);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x3, y3);
gaiaSetPoint (ln->Coords, 1, x1, y1);
}
else if (mode < 0)
{
/* multipoint */
gaiaAddPointToGeomColl (result, x1, y1);
gaiaAddPointToGeomColl (result, x2, y2);
gaiaAddPointToGeomColl (result, x3, y3);
}
else
{
/* polygon */
pg = gaiaAddPolygonToGeomColl (result, 4, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x1, y1);
}
}
gaiaFreeGeomColl (item);
item = gaiaAllocGeomColl ();
pg = gaiaAddPolygonToGeomColl (item, 4, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x3, y3);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x4, y4);
gaiaSetPoint (rng->Coords, 3, x3, y3);
gaiaMbrGeometry (item);
if (p_cache != NULL)
ret = gaiaGeomCollIntersects_r (p_cache, geom, item);
else
ret = gaiaGeomCollIntersects (geom, item);
if (ret == 1)
{
/* ok, inserting a valid cell [pointing downside] */
count++;
if (mode > 0)
{
/* multilinestring */
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x1, y1);
gaiaSetPoint (ln->Coords, 1, x2, y2);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x2, y2);
gaiaSetPoint (ln->Coords, 1, x3, y3);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x3, y3);
gaiaSetPoint (ln->Coords, 1, x1, y1);
}
else if (mode < 0)
{
/* multipoint */
gaiaAddPointToGeomColl (result, x1, y1);
gaiaAddPointToGeomColl (result, x2, y2);
gaiaAddPointToGeomColl (result, x3, y3);
}
else
{
/* polygon */
pg = gaiaAddPolygonToGeomColl (result, 4, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x3, y3);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x4, y4);
gaiaSetPoint (rng->Coords, 3, x3, y3);
}
}
gaiaFreeGeomColl (item);
x1 += shift_h_even;
x2 += shift_h_even;
x3 += shift_h_even;
x4 += shift_h_even;
}
base_y += shift_v;
if (odd_even)
odd_even = 0;
else
odd_even = 1;
}
/* final check */
if (!count)
{
/* empty grid */
gaiaFreeGeomColl (result);
return NULL;
}
if (mode == 0)
{
result->DeclaredType = GAIA_MULTIPOLYGON;
return result;
}
item = result;
if (p_cache != NULL)
result = gaiaUnaryUnion_r (p_cache, item);
else
result = gaiaUnaryUnion (item);
gaiaFreeGeomColl (item);
result->Srid = geom->Srid;
if (mode < 0)
result->DeclaredType = GAIA_MULTIPOINT;
else
result->DeclaredType = GAIA_MULTILINESTRING;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTriangularGrid (gaiaGeomCollPtr geom, double origin_x, double origin_y,
double size, int mode)
{
return gaiaTriangularGridCommon (NULL, geom, origin_x, origin_y, size,
mode);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTriangularGrid_r (const void *p_cache, gaiaGeomCollPtr geom,
double origin_x, double origin_y, double size, int mode)
{
return gaiaTriangularGridCommon (p_cache, geom, origin_x, origin_y, size,
mode);
}
static void
get_hexgrid_base (double min_x, double min_y, double origin_x, double origin_y,
double shift3, double shift4, double shift,
int *odd_even, double *base_x, double *base_y)
{
/* determining the grid base-point [MinX/MinY] for am Hexagonal Grid */
double bx = origin_x;
double by = origin_y;
while (1)
{
/* looping on grid rows */
if (min_y < origin_y)
{
/* going southward */
if (by > min_y)
goto next_scanline;
if (*odd_even)
bx = origin_x - (shift3 / 2.0);
else
bx = origin_x;
}
else
{
/* going northward */
if (by < min_y)
goto next_scanline;
if (*odd_even)
bx = origin_x + (shift3 / 2.0);
else
bx = origin_x;
}
while (1)
{
/* looping on grid columns */
if (min_x < origin_x)
{
/* going westward */
if (bx - shift4 < min_x)
{
*base_x = bx;
*base_y = by;
return;
}
bx -= shift3;
}
else
{
/* going eastward */
if (bx + shift4 > min_x)
{
*base_x = bx;
*base_y = by;
return;
}
bx += shift3;
}
}
next_scanline:
if (min_y < origin_y)
by -= shift;
else
by += shift;
if (*odd_even)
*odd_even = 0;
else
*odd_even = 1;
}
}
static gaiaGeomCollPtr
gaiaHexagonalGridCommon (const void *p_cache, gaiaGeomCollPtr geom,
double origin_x, double origin_y, double size,
int mode)
{
/* creating a regular grid [Hexagonal cells] */
double min_x;
double min_y;
double max_x;
double max_y;
double base_x;
double base_y;
double x1;
double y1;
double x2;
double y2;
double x3;
double y3;
double x4;
double y4;
double x5;
double y5;
double x6;
double y6;
int count = 0;
int odd_even = 0;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaLinestringPtr ln;
gaiaGeomCollPtr result = NULL;
gaiaGeomCollPtr item = NULL;
double shift;
double shift2;
double shift3;
double shift4;
int ret;
if (size <= 0.0)
return NULL;
shift = size * sin (3.14159265358979323846 / 3.0);
shift2 = size / 2.0;
shift3 = size * 3.0;
shift4 = size * 2.0;
result = gaiaAllocGeomColl ();
result->Srid = geom->Srid;
get_grid_bbox (geom, &min_x, &min_y, &max_x, &max_y);
get_hexgrid_base (min_x, min_y, origin_x, origin_y, shift3, shift4,
shift, &odd_even, &base_x, &base_y);
base_x -= shift3;
base_y -= shift;
while ((base_y - shift) < max_y)
{
/* looping on grid rows */
if (odd_even)
x1 = base_x - (shift3 / 2.0);
else
x1 = base_x;
y1 = base_y;
x2 = x1 + shift2;
y2 = y1 - shift;
x3 = x2 + size;
y3 = y2;
x4 = x1 + shift4;
y4 = y1;
x5 = x3;
y5 = y1 + shift;
x6 = x2;
y6 = y5;
while (x1 < max_x)
{
/* looping on grid columns */
item = gaiaAllocGeomColl ();
pg = gaiaAddPolygonToGeomColl (item, 7, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x4, y4);
gaiaSetPoint (rng->Coords, 4, x5, y5);
gaiaSetPoint (rng->Coords, 5, x6, y6);
gaiaSetPoint (rng->Coords, 6, x1, y1);
gaiaMbrGeometry (item);
if (p_cache != NULL)
ret = gaiaGeomCollIntersects_r (p_cache, geom, item);
else
ret = gaiaGeomCollIntersects (geom, item);
if (ret == 1)
{
/* ok, inserting a valid cell */
count++;
if (mode > 0)
{
/* multilinestring */
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x1, y1);
gaiaSetPoint (ln->Coords, 1, x2, y2);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x2, y2);
gaiaSetPoint (ln->Coords, 1, x3, y3);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x3, y3);
gaiaSetPoint (ln->Coords, 1, x4, y4);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x4, y4);
gaiaSetPoint (ln->Coords, 1, x5, y5);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x5, y5);
gaiaSetPoint (ln->Coords, 1, x6, y6);
ln = gaiaAddLinestringToGeomColl (result, 2);
gaiaSetPoint (ln->Coords, 0, x6, y6);
gaiaSetPoint (ln->Coords, 1, x1, y1);
}
else if (mode < 0)
{
/* multipoint */
gaiaAddPointToGeomColl (result, x1, y1);
gaiaAddPointToGeomColl (result, x2, y2);
gaiaAddPointToGeomColl (result, x3, y3);
gaiaAddPointToGeomColl (result, x4, y4);
gaiaAddPointToGeomColl (result, x5, y5);
gaiaAddPointToGeomColl (result, x6, y6);
}
else
{
/* polygon */
pg = gaiaAddPolygonToGeomColl (result, 7, 0);
rng = pg->Exterior;
gaiaSetPoint (rng->Coords, 0, x1, y1);
gaiaSetPoint (rng->Coords, 1, x2, y2);
gaiaSetPoint (rng->Coords, 2, x3, y3);
gaiaSetPoint (rng->Coords, 3, x4, y4);
gaiaSetPoint (rng->Coords, 4, x5, y5);
gaiaSetPoint (rng->Coords, 5, x6, y6);
gaiaSetPoint (rng->Coords, 6, x1, y1);
}
}
gaiaFreeGeomColl (item);
x1 += shift3;
x2 += shift3;
x3 += shift3;
x4 += shift3;
x5 += shift3;
x6 += shift3;
}
base_y += shift;
if (odd_even)
odd_even = 0;
else
odd_even = 1;
}
/* final check */
if (!count)
{
/* empty grid */
gaiaFreeGeomColl (result);
return NULL;
}
if (mode == 0)
{
result->DeclaredType = GAIA_MULTIPOLYGON;
return result;
}
item = result;
if (p_cache != NULL)
result = gaiaUnaryUnion_r (p_cache, item);
else
result = gaiaUnaryUnion (item);
gaiaFreeGeomColl (item);
result->Srid = geom->Srid;
if (mode < 0)
result->DeclaredType = GAIA_MULTIPOINT;
else
result->DeclaredType = GAIA_MULTILINESTRING;
return result;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaHexagonalGrid (gaiaGeomCollPtr geom, double origin_x, double origin_y,
double size, int mode)
{
return gaiaHexagonalGridCommon (NULL, geom, origin_x, origin_y, size, mode);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaHexagonalGrid_r (const void *p_cache, gaiaGeomCollPtr geom, double origin_x,
double origin_y, double size, int mode)
{
return gaiaHexagonalGridCommon (p_cache, geom, origin_x, origin_y, size,
mode);
}
#endif /* end including GEOS */
libspatialite-5.1.0/src/gaiageo/gg_shape.c 0000644 0001750 0001750 00000512410 14463127014 015375 0000000 0000000 /*
gg_shape.c -- Gaia shapefile handling
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#ifdef _WIN32
#include
#endif
#if OMIT_ICONV == 0 /* if ICONV is disabled no SHP support is available */
#if defined(__MINGW32__) || defined(_WIN32)
#define LIBICONV_STATIC
#include
#define LIBCHARSET_STATIC
#ifdef _MSC_VER
/* isn't supported on OSGeo4W */
/* applying a tricky workaround to fix this issue */
extern const char *locale_charset (void);
#else /* sane Windows - not OSGeo4W */
#include
#endif /* end localcharset */
#else /* not MINGW32 */
#if defined(__APPLE__) || defined(__ANDROID__)
#include
#include
#else /* neither Mac OsX nor Android */
#include
#include
#endif
#endif
#include
#include
#include
#ifdef _WIN32
#define atoll _atoi64
#endif /* not WIN32 */
/* 64 bit integer: portable format for printf() */
#if defined(_WIN32) && !defined(__MINGW32__)
#define FRMT64 "%I64d"
#else
#define FRMT64 "%lld"
#endif
#define SHAPEFILE_NO_DATA 1e-38
#ifdef _WIN32
#define strcasecmp _stricmp
#endif /* not WIN32 */
struct auxdbf_fld
{
/* auxiliary DBF field struct */
char *name;
struct auxdbf_fld *next;
};
struct auxdbf_list
{
/* auxiliary DBF struct */
struct auxdbf_fld *first;
struct auxdbf_fld *last;
};
GAIAGEO_DECLARE void
gaiaFreeValue (gaiaValuePtr p)
{
/* frees all memory allocations for this DBF Field value */
if (!p)
return;
if (p->TxtValue)
free (p->TxtValue);
free (p);
}
GAIAGEO_DECLARE void
gaiaSetNullValue (gaiaDbfFieldPtr field)
{
/* assignes a NULL value to some DBF field */
if (field->Value)
gaiaFreeValue (field->Value);
field->Value = malloc (sizeof (gaiaValue));
field->Value->Type = GAIA_NULL_VALUE;
field->Value->TxtValue = NULL;
}
GAIAGEO_DECLARE void
gaiaSetIntValue (gaiaDbfFieldPtr field, sqlite3_int64 value)
{
/* assignes an INTEGER value to some DBF field */
if (field->Value)
gaiaFreeValue (field->Value);
field->Value = malloc (sizeof (gaiaValue));
field->Value->Type = GAIA_INT_VALUE;
field->Value->TxtValue = NULL;
field->Value->IntValue = value;
}
GAIAGEO_DECLARE void
gaiaSetDoubleValue (gaiaDbfFieldPtr field, double value)
{
/* assignes a DOUBLE value to some DBF field */
if (field->Value)
gaiaFreeValue (field->Value);
field->Value = malloc (sizeof (gaiaValue));
field->Value->Type = GAIA_DOUBLE_VALUE;
field->Value->TxtValue = NULL;
field->Value->DblValue = value;
}
GAIAGEO_DECLARE void
gaiaSetStrValue (gaiaDbfFieldPtr field, char *str)
{
/* assignes a STRING value to some DBF field */
int len = strlen (str);
if (field->Value)
gaiaFreeValue (field->Value);
field->Value = malloc (sizeof (gaiaValue));
field->Value->Type = GAIA_TEXT_VALUE;
field->Value->TxtValue = malloc (len + 1);
strcpy (field->Value->TxtValue, str);
}
GAIAGEO_DECLARE int
gaiaMemFseek (gaiaMemFilePtr mem, off_t offset)
{
/* repositioning a Memory File */
if (mem == NULL)
return -1;
if (mem->buf == NULL)
return -1;
if (offset < 0)
return -1;
if (offset >= (off_t)mem->size)
return -1;
mem->offset = offset;
return 0;
}
GAIAGEO_DECLARE size_t
gaiaMemRead (void *ptr, size_t bytes, gaiaMemFilePtr mem)
{
/* reading from Memory File */
size_t rd = 0;
size_t i;
unsigned char *in;
unsigned char *out;
if (mem == NULL)
return 0;
if (mem->buf == NULL)
return 0;
for (i = 0; i < bytes; i++)
{
if (mem->offset >= mem->size)
break;
in = (unsigned char *) (mem->buf) + mem->offset;
out = (unsigned char *) ptr + i;
*out = *in;
mem->offset += 1;
rd++;
}
return rd;
}
GAIAGEO_DECLARE gaiaDbfFieldPtr
gaiaAllocDbfField (char *name, unsigned char type,
int offset, unsigned char length, unsigned char decimals)
{
/* allocates and initializes a DBF Field definition */
gaiaDbfFieldPtr p = malloc (sizeof (gaiaDbfField));
int len = strlen (name);
p->Name = malloc (len + 1);
strcpy (p->Name, name);
p->Type = type;
p->Offset = offset;
p->Length = length;
p->Decimals = decimals;
p->Value = NULL;
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE void
gaiaFreeDbfField (gaiaDbfFieldPtr p)
{
/* frees all memory allocations for this DBF Field definition */
if (!p)
return;
if (p->Name)
free (p->Name);
if (p->Value)
gaiaFreeValue (p->Value);
free (p);
}
GAIAGEO_DECLARE gaiaDbfFieldPtr
gaiaCloneDbfField (gaiaDbfFieldPtr org)
{
/* creating a new DBF LIST copied from the original one */
gaiaDbfFieldPtr p = malloc (sizeof (gaiaDbfField));
int len = strlen (org->Name);
p->Name = malloc (len + 1);
strcpy (p->Name, org->Name);
p->Type = org->Type;
p->Offset = org->Offset;
p->Length = org->Length;
p->Decimals = org->Decimals;
p->Value = gaiaCloneValue (org->Value);
p->Next = NULL;
return p;
}
GAIAGEO_DECLARE gaiaDbfListPtr
gaiaAllocDbfList ()
{
/* allocates and initializes the DBF Fields list */
gaiaDbfListPtr list = malloc (sizeof (gaiaDbfList));
list->RowId = 0;
list->Geometry = NULL;
list->First = NULL;
list->Last = NULL;
return list;
}
GAIAGEO_DECLARE void
gaiaFreeDbfList (gaiaDbfListPtr list)
{
/* frees all memory allocations related to DBF Fields list */
gaiaDbfFieldPtr p;
gaiaDbfFieldPtr pn;
if (!list)
return;
p = list->First;
while (p)
{
pn = p->Next;
gaiaFreeDbfField (p);
p = pn;
}
if (list->Geometry)
gaiaFreeGeomColl (list->Geometry);
free (list);
}
GAIAGEO_DECLARE int
gaiaIsValidDbfList (gaiaDbfListPtr list)
{
/* checks if the DBF fields list contains any invalid data type */
gaiaDbfFieldPtr p;
if (!list)
return 0;
p = list->First;
while (p)
{
if (p->Type == 'N' || p->Type == 'C' || p->Type == 'L'
|| p->Type == 'D' || p->Type == 'F')
;
else
return 0;
p = p->Next;
}
return 1;
}
GAIAGEO_DECLARE gaiaDbfFieldPtr
gaiaAddDbfField (gaiaDbfListPtr list, char *name, unsigned char type,
int offset, unsigned char length, unsigned char decimals)
{
/* inserts a Field in the DBF Fields list */
gaiaDbfFieldPtr p;
if (!list)
return NULL;
p = gaiaAllocDbfField (name, type, offset, length, decimals);
if (!(list->First))
list->First = p;
if (list->Last)
list->Last->Next = p;
list->Last = p;
return p;
}
GAIAGEO_DECLARE void
gaiaResetDbfEntity (gaiaDbfListPtr list)
{
/* resets data values */
gaiaDbfFieldPtr p;
if (!list)
return;
p = list->First;
while (p)
{
if (p->Value)
gaiaFreeValue (p->Value);
p->Value = NULL;
p = p->Next;
}
if (list->Geometry)
gaiaFreeGeomColl (list->Geometry);
list->Geometry = NULL;
}
GAIAGEO_DECLARE gaiaValuePtr
gaiaCloneValue (gaiaValuePtr org)
{
/* creating a new VARIANT value copied from the original one */
gaiaValuePtr value;
int len;
value = malloc (sizeof (gaiaValue));
value->Type = GAIA_NULL_VALUE;
value->TxtValue = NULL;
switch (org->Type)
{
case GAIA_INT_VALUE:
value->Type = GAIA_INT_VALUE;
value->IntValue = org->IntValue;
break;
case GAIA_DOUBLE_VALUE:
value->Type = GAIA_DOUBLE_VALUE;
value->DblValue = org->DblValue;
break;
case GAIA_TEXT_VALUE:
value->Type = GAIA_TEXT_VALUE;
len = strlen (org->TxtValue);
value->TxtValue = malloc (len + 1);
strcpy (value->TxtValue, org->TxtValue);
};
return value;
}
GAIAGEO_DECLARE gaiaDbfListPtr
gaiaCloneDbfEntity (gaiaDbfListPtr org)
{
/* creating a new DBF LIST copied from the original one */
gaiaDbfFieldPtr p;
gaiaDbfFieldPtr newFld;
gaiaDbfListPtr entity = gaiaAllocDbfList ();
entity->RowId = org->RowId;
if (org->Geometry)
entity->Geometry = gaiaCloneGeomColl (org->Geometry);
p = org->First;
while (p)
{
newFld =
gaiaAddDbfField (entity, p->Name, p->Type, p->Offset, p->Length,
p->Decimals);
if (p->Value)
newFld->Value = gaiaCloneValue (p->Value);
p = p->Next;
}
return entity;
}
GAIAGEO_DECLARE gaiaShapefilePtr
gaiaAllocShapefile ()
{
/* 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->memShp = NULL;
shp->memShx = NULL;
shp->memDbf = NULL;
shp->Dbf = NULL;
shp->BufShp = NULL;
shp->ShpBfsz = 0;
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;
}
GAIAGEO_DECLARE void
gaiaFreeShapefile (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->IconvObj)
iconv_close ((iconv_t) shp->IconvObj);
if (shp->LastError)
free (shp->LastError);
free (shp);
}
GAIAGEO_DECLARE void
gaiaOpenShpRead (gaiaShapefilePtr shp, const char *path, const char *charFrom,
const char *charTo)
{
/* 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[4192];
iconv_t iconv_ret;
char utf8buf[2048];
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int endian_arch = gaiaEndianArch ();
gaiaDbfListPtr dbf_list = NULL;
if (charFrom && charTo)
{
iconv_ret = iconv_open (charTo, charFrom);
if (iconv_ret == (iconv_t) (-1))
{
sprintf (errMsg, "conversion from '%s' to '%s' not available\n",
charFrom, charTo);
goto unsupported_conversion;
}
shp->IconvObj = iconv_ret;
}
else
{
sprintf (errMsg, "a NULL charset-name was passed\n");
goto unsupported_conversion;
}
if (shp->flShp != NULL || shp->flShx != NULL || shp->flDbf != NULL)
{
sprintf (errMsg,
"attempting to reopen an already opened Shapefile\n");
goto unsupported_conversion;
}
if (shp->memShx == NULL)
{
sprintf (xpath, "%s.shx", path);
#ifdef _WIN32
fl_shx = gaia_win_fopen (xpath, "rb");
#else
fl_shx = fopen (xpath, "rb");
#endif
if (!fl_shx)
{
sys_err = strerror (errno);
sprintf (errMsg, "unable to open '%s' for reading: %s", xpath,
sys_err);
goto no_file;
}
}
if (shp->memShp == NULL)
{
sprintf (xpath, "%s.shp", path);
#ifdef _WIN32
fl_shp = gaia_win_fopen (xpath, "rb");
#else
fl_shp = fopen (xpath, "rb");
#endif
if (!fl_shp)
{
sys_err = strerror (errno);
sprintf (errMsg, "unable to open '%s' for reading: %s", xpath,
sys_err);
goto no_file;
}
}
if (shp->memDbf == NULL)
{
sprintf (xpath, "%s.dbf", path);
#ifdef _WIN32
fl_dbf = gaia_win_fopen (xpath, "rb");
#else
fl_dbf = fopen (xpath, "rb");
#endif
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 */
if (shp->memShx != NULL)
rd = gaiaMemRead (buf_shx, 100, shp->memShx);
else
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;
/* reading SHP file header */
buf_shp = malloc (sizeof (unsigned char) * buf_size);
if (shp->memShp != NULL)
rd = gaiaMemRead (buf_shp, 100, shp->memShp);
else
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;
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;
shp->MinX = gaiaImport64 (buf_shp + 36, GAIA_LITTLE_ENDIAN, endian_arch);
shp->MinY = gaiaImport64 (buf_shp + 44, GAIA_LITTLE_ENDIAN, endian_arch);
shp->MaxX = gaiaImport64 (buf_shp + 52, GAIA_LITTLE_ENDIAN, endian_arch);
shp->MaxY = gaiaImport64 (buf_shp + 60, GAIA_LITTLE_ENDIAN, endian_arch);
/* reading DBF file header */
if (shp->memDbf != NULL)
rd = gaiaMemRead (bf, 32, shp->memDbf);
else
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 */
if ((dbf_size - ind) < 32)
{
/* some odd DBF could contain some unexpected extra-padding */
int extra = dbf_size - ind;
if (shp->memDbf != NULL)
rd = gaiaMemRead (bf, extra, shp->memDbf);
else
rd = fread (bf, sizeof (unsigned char), extra, fl_dbf);
if (rd != extra)
goto error;
/* ignoring the extra-padding */
break;
}
if (shp->memDbf != NULL)
rd = gaiaMemRead (bf, 32, shp->memDbf);
else
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);
spatialite_e
("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';
len = strlen ((char *) field_name);
utf8len = 2048;
pBuf = (char *) field_name;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (shp->IconvObj), &pBuf, &len, &pUtf8buf,
&utf8len) == (size_t) (-1))
{
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n",
field_name);
goto conversion_error;
}
memcpy (field_name, utf8buf, 2048 - utf8len);
field_name[2048 - utf8len] = '\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;
conversion_error:
/* libiconv error */
if (shp->LastError)
free (shp->LastError);
sprintf (errMsg, "'%s.dbf' field name: invalid character sequence", 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 struct auxdbf_list *
alloc_auxdbf (gaiaDbfListPtr dbf_list)
{
/* allocating the auxiliary DBF struct */
int len;
gaiaDbfFieldPtr fld;
struct auxdbf_fld *fld_ex;
struct auxdbf_list *auxdbf = malloc (sizeof (struct auxdbf_list));
auxdbf->first = NULL;
auxdbf->last = NULL;
fld = dbf_list->First;
while (fld)
{
fld_ex = malloc (sizeof (struct auxdbf_fld));
len = strlen (fld->Name);
fld_ex->name = malloc (len + 1);
strcpy (fld_ex->name, fld->Name);
fld_ex->next = NULL;
if (auxdbf->first == NULL)
auxdbf->first = fld_ex;
if (auxdbf->last != NULL)
auxdbf->last->next = fld_ex;
auxdbf->last = fld_ex;
fld = fld->Next;
}
return auxdbf;
}
static void
free_auxdbf (struct auxdbf_list *auxdbf)
{
/* freeing an auxiliary DBF struct */
struct auxdbf_fld *n_fld;
struct auxdbf_fld *fld = auxdbf->first;
while (fld != NULL)
{
n_fld = fld->next;
if (fld->name != NULL)
free (fld->name);
free (fld);
fld = n_fld;
}
free (auxdbf);
}
static void
truncate_long_name (struct auxdbf_list *list, gaiaDbfFieldPtr xfld)
{
/* attempting to create a unique short name <= 10 bytes */
char suffix;
char buf[16];
struct auxdbf_fld *fld;
struct auxdbf_fld *base = NULL;
memcpy (buf, xfld->Name, 9);
buf[10] = '\0';
fld = list->first;
while (fld)
{
/* identifying the base aux Field */
if (strcmp (xfld->Name, fld->name) == 0)
{
base = fld;
break;
}
fld = fld->next;
}
suffix = '0';
while (1)
{
/* attempting to find a numeric suffix ensuring uniqueness */
int ok = 1;
buf[9] = suffix;
fld = list->first;
while (fld)
{
if (base != fld)
{
if (strcasecmp (buf, fld->name) == 0)
{
/* invalid: already defined */
ok = 0;
break;
}
}
fld = fld->next;
}
if (ok)
{
strcpy (xfld->Name, buf);
if (base != NULL)
strcpy (base->name, buf);
return;
}
if (suffix == '9')
break;
else
suffix++;
}
suffix = 'A';
while (1)
{
/* attempting to find a letter suffix ensuring uniqueness */
int ok = 1;
buf[9] = suffix;
fld = list->first;
while (fld)
{
if (base != fld)
{
if (strcasecmp (buf, fld->name) == 0)
{
/* invalid: already defined */
ok = 0;
break;
}
}
fld = fld->next;
}
if (ok)
{
strcpy (xfld->Name, buf);
if (base != NULL)
strcpy (base->name, buf);
return;
}
if (suffix == 'Z')
break;
else
suffix++;
}
}
static void
convert_dbf_colname_case (char *buf, int colname_case)
{
/* converts a DBF column-name to Lower- or Upper-case */
char *p = buf;
while (*p != '\0')
{
if (colname_case == GAIA_DBF_COLNAME_LOWERCASE)
{
if (*p >= 'A' && *p <= 'Z')
*p = *p - 'A' + 'a';
}
if (colname_case == GAIA_DBF_COLNAME_UPPERCASE)
{
if (*p >= 'a' && *p <= 'z')
*p = *p - 'a' + 'A';
}
p++;
}
}
GAIAGEO_DECLARE void
gaiaOpenShpWrite (gaiaShapefilePtr shp, const char *path, int shape,
gaiaDbfListPtr dbf_list, const char *charFrom,
const char *charTo)
{
/* trying to create the shapefile */
gaiaOpenShpWriteEx (shp, path, shape, dbf_list, charFrom, charTo,
GAIA_DBF_COLNAME_CASE_IGNORE);
}
GAIAGEO_DECLARE void
gaiaOpenShpWriteEx (gaiaShapefilePtr shp, const char *path, int shape,
gaiaDbfListPtr dbf_list, const char *charFrom,
const char *charTo, int colname_case)
{
/* 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[4192];
short dbf_reclen = 0;
int shp_size = 0;
int shx_size = 0;
unsigned short dbf_size = 0;
iconv_t iconv_ret;
int endian_arch = gaiaEndianArch ();
char buf[2048];
char utf8buf[2048];
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int defaultId = 1;
struct auxdbf_list *auxdbf = NULL;
if (charFrom && charTo)
{
iconv_ret = iconv_open (charTo, charFrom);
if (iconv_ret == (iconv_t) (-1))
{
sprintf (errMsg, "conversion from '%s' to '%s' not available\n",
charFrom, charTo);
goto unsupported_conversion;
}
shp->IconvObj = iconv_ret;
}
else
{
sprintf (errMsg, "a NULL charset-name was passed\n");
goto unsupported_conversion;
}
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);
#ifdef _WIN32
fl_shx = gaia_win_fopen (xpath, "wb");
#else
fl_shx = fopen (xpath, "wb");
#endif
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);
#ifdef _WIN32
fl_shp = gaia_win_fopen (xpath, "wb");
#else
fl_shp = fopen (xpath, "wb");
#endif
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);
#ifdef _WIN32
fl_dbf = gaia_win_fopen (xpath, "wb");
#else
fl_dbf = fopen (xpath, "wb");
#endif
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 */
auxdbf = alloc_auxdbf (dbf_list);
fld = dbf_list->First;
while (fld)
{
/* exporting DBF Fields specifications */
memset (buf_shp, 0, 32);
if (strlen (fld->Name) > 10)
{
/* long name: attempting to safely truncate */
truncate_long_name (auxdbf, fld);
}
strcpy (buf, fld->Name);
len = strlen (buf);
utf8len = 2048;
pBuf = buf;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (shp->IconvObj), &pBuf, &len, &pUtf8buf,
&utf8len) == (size_t) (-1))
sprintf (buf, "FLD#%d", defaultId++);
else
{
memcpy (buf, utf8buf, 2048 - utf8len);
buf[2048 - utf8len] = '\0';
if (strlen (buf) > 10)
sprintf (buf, "FLD#%d", defaultId++);
}
convert_dbf_colname_case (buf, colname_case);
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;
}
free_auxdbf (auxdbf);
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;
switch (shape)
{
/* setting up SHAPE and dimensions */
case GAIA_POINT:
shp->Shape = GAIA_SHP_POINT;
shp->EffectiveType = GAIA_POINT;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_POINTZ:
shp->Shape = GAIA_SHP_POINTZ;
shp->EffectiveType = GAIA_POINT;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_POINTM:
shp->Shape = GAIA_SHP_POINTM;
shp->EffectiveType = GAIA_POINT;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_POINTZM:
shp->Shape = GAIA_SHP_POINTZ;
shp->EffectiveType = GAIA_POINT;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
case GAIA_MULTIPOINT:
shp->Shape = GAIA_SHP_MULTIPOINT;
shp->EffectiveType = GAIA_MULTIPOINT;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_MULTIPOINTZ:
shp->Shape = GAIA_SHP_MULTIPOINTZ;
shp->EffectiveType = GAIA_MULTIPOINT;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_MULTIPOINTM:
shp->Shape = GAIA_SHP_MULTIPOINTM;
shp->EffectiveType = GAIA_MULTIPOINT;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_MULTIPOINTZM:
shp->Shape = GAIA_SHP_MULTIPOINTZ;
shp->EffectiveType = GAIA_MULTIPOINT;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
case GAIA_LINESTRING:
shp->Shape = GAIA_SHP_POLYLINE;
shp->EffectiveType = GAIA_LINESTRING;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_LINESTRINGZ:
shp->Shape = GAIA_SHP_POLYLINEZ;
shp->EffectiveType = GAIA_LINESTRING;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_LINESTRINGM:
shp->Shape = GAIA_SHP_POLYLINEM;
shp->EffectiveType = GAIA_LINESTRING;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_LINESTRINGZM:
shp->Shape = GAIA_SHP_POLYLINEZ;
shp->EffectiveType = GAIA_LINESTRING;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
case GAIA_MULTILINESTRING:
shp->Shape = GAIA_SHP_POLYLINE;
shp->EffectiveType = GAIA_MULTILINESTRING;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_MULTILINESTRINGZ:
shp->Shape = GAIA_SHP_POLYLINEZ;
shp->EffectiveType = GAIA_MULTILINESTRING;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_MULTILINESTRINGM:
shp->Shape = GAIA_SHP_POLYLINEM;
shp->EffectiveType = GAIA_MULTILINESTRING;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_MULTILINESTRINGZM:
shp->Shape = GAIA_SHP_POLYLINEZ;
shp->EffectiveType = GAIA_MULTILINESTRING;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
case GAIA_POLYGON:
shp->Shape = GAIA_SHP_POLYGON;
shp->EffectiveType = GAIA_POLYGON;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_POLYGONZ:
shp->Shape = GAIA_SHP_POLYGONZ;
shp->EffectiveType = GAIA_POLYGON;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_POLYGONM:
shp->Shape = GAIA_SHP_POLYGONM;
shp->EffectiveType = GAIA_POLYGON;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_POLYGONZM:
shp->Shape = GAIA_SHP_POLYGONZ;
shp->EffectiveType = GAIA_POLYGON;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
case GAIA_MULTIPOLYGON:
shp->Shape = GAIA_SHP_POLYGON;
shp->EffectiveType = GAIA_MULTIPOLYGON;
shp->EffectiveDims = GAIA_XY;
break;
case GAIA_MULTIPOLYGONZ:
shp->Shape = GAIA_SHP_POLYGONZ;
shp->EffectiveType = GAIA_MULTIPOLYGON;
shp->EffectiveDims = GAIA_XY_Z;
break;
case GAIA_MULTIPOLYGONM:
shp->Shape = GAIA_SHP_POLYGONM;
shp->EffectiveType = GAIA_MULTIPOLYGON;
shp->EffectiveDims = GAIA_XY_M;
break;
case GAIA_MULTIPOLYGONZM:
shp->Shape = GAIA_SHP_POLYGONZ;
shp->EffectiveType = GAIA_MULTIPOLYGON;
shp->EffectiveDims = GAIA_XY_Z_M;
break;
};
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 double
to_sqlite_julian_date (int year, int month, int day, double *julian)
{
/* trying to convert an 'YYYY-MM-DD' date into a JulianDate [double] */
int Y;
int M;
int D;
int A;
int B;
int X1;
int X2;
if (year < 1900 || year > 2400)
return 0;
if (month < 1 || month > 12)
return 0;
if (day < 1)
return 0;
switch (month)
{
case 2:
if ((year / 4) == 0)
{
if (day > 29)
return 0;
}
else
{
if (day > 28)
return 0;
}
break;
case 4:
case 6:
case 9:
case 11:
if (day > 30)
return 0;
break;
default:
if (day > 31)
return 0;
};
/* computing the Julian date */
Y = year;
M = month;
D = day;
if (M <= 2)
{
Y--;
M += 12;
}
A = Y / 100;
B = 2 - A + (A / 4);
X1 = 36525 * (Y + 4716) / 100;
X2 = 306001 * (M + 1) / 10000;
*julian = (double) (X1 + X2 + D + B - 1524.5);
return 1;
}
static int
parseDbfField (unsigned char *buf_dbf, void *iconv_obj, gaiaDbfFieldPtr pFld,
int text_dates)
{
/* parsing a generic DBF field */
unsigned char buf[512];
char utf8buf[2048];
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int i;
memcpy (buf, buf_dbf + pFld->Offset + 1, pFld->Length);
buf[pFld->Length] = '\0';
if (*buf == '\0')
gaiaSetNullValue (pFld);
else
{
if (pFld->Type == 'N')
{
/* NUMERIC value */
if (pFld->Decimals > 0 || pFld->Length > 18)
gaiaSetDoubleValue (pFld, atof ((char *) buf));
else
gaiaSetIntValue (pFld, atoll ((char *) buf));
}
else if (pFld->Type == 'M')
{
/* MEMO value - assumed to always be NULL */
gaiaSetNullValue (pFld);
}
else if (pFld->Type == 'F')
{
/* FLOAT value */
gaiaSetDoubleValue (pFld, atof ((char *) buf));
}
else if (pFld->Type == 'D')
{
/* DATE value */
if (text_dates)
{
/* assuming to be plain text */
gaiaSetStrValue (pFld, (char *) buf);
}
else
{
if (strlen ((char *) buf) != 8)
gaiaSetNullValue (pFld);
else
{
/* converting into a Julian Date */
double julian;
char date[5];
int year = 0;
int month = 0;
int day = 0;
date[0] = buf[0];
date[1] = buf[1];
date[2] = buf[2];
date[3] = buf[3];
date[4] = '\0';
year = atoi (date);
date[0] = buf[4];
date[1] = buf[5];
date[2] = '\0';
month = atoi (date);
date[0] = buf[6];
date[1] = buf[7];
date[2] = '\0';
day = atoi (date);
if (to_sqlite_julian_date
(year, month, day, &julian))
gaiaSetDoubleValue (pFld, julian);
else
gaiaSetNullValue (pFld);
}
}
}
else if (pFld->Type == 'L')
{
/* LOGICAL [aka Boolean] value */
if (*buf == '1' || *buf == 't' || *buf == 'T'
|| *buf == 'Y' || *buf == 'y')
gaiaSetIntValue (pFld, 1);
else
gaiaSetIntValue (pFld, 0);
}
else
{
/* CHARACTER [aka String, Text] value */
/* Sandro 2013-01-07
/ fixing an issue reported by Filip Arlet
for (i = strlen ((char *) buf) - 1; i > 1; i--)
*/
for (i = strlen ((char *) buf) - 1; i >= 0; i--)
{
/* cleaning up trailing spaces */
if (buf[i] == ' ')
buf[i] = '\0';
else
break;
}
len = strlen ((char *) buf);
utf8len = 2048;
pBuf = (char *) buf;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (iconv_obj), &pBuf, &len, &pUtf8buf,
&utf8len) == (size_t) (-1))
return 0;
memcpy (buf, utf8buf, 2048 - utf8len);
buf[2048 - utf8len] = '\0';
gaiaSetStrValue (pFld, (char *) buf);
}
}
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;
}
}
GAIAGEO_DECLARE int
gaiaReadShpEntity (gaiaShapefilePtr shp, int current_row, int srid)
{
return gaiaReadShpEntity_ex (shp, current_row, srid, 0);
}
GAIAGEO_DECLARE int
gaiaReadShpEntity_ex (gaiaShapefilePtr shp, int current_row, int srid,
int text_dates)
{
/* trying to read an entity from shapefile */
unsigned char buf[512];
int len;
int rd;
int skpos;
gaia_off_t offset;
int off_shp;
int sz;
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;
char errMsg[1024];
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line = NULL;
gaiaRingPtr ring = NULL;
gaiaDbfFieldPtr pFld;
struct shp_ring_collection ringsColl;
/* initializing the RING collection */
ringsColl.First = NULL;
ringsColl.Last = NULL;
/* positioning and reading the SHX file */
offset = 100 + ((gaia_off_t) current_row * (gaia_off_t) 8); /* 100 bytes for the header + current row displacement; each SHX row = 8 bytes */
if (shp->memShx != NULL)
skpos = gaiaMemFseek (shp->memShx, offset);
else
skpos = gaia_fseek (shp->flShx, offset, SEEK_SET);
if (skpos != 0)
goto eof;
if (shp->memDbf != NULL)
rd = gaiaMemRead (buf, 8, shp->memShx);
else
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 +
((gaia_off_t) current_row * (gaia_off_t) (shp->DbfReclen));
if (shp->memDbf != NULL)
skpos = gaiaMemFseek (shp->memDbf, offset);
else
skpos = gaia_fseek (shp->flDbf, offset, SEEK_SET);
if (skpos != 0)
goto error;
if (shp->memDbf != NULL)
rd = gaiaMemRead (shp->BufDbf, shp->DbfReclen, shp->memDbf);
else
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 = (gaia_off_t) off_shp *2;
if (shp->memShp != NULL)
skpos = gaiaMemFseek (shp->memShp, offset);
else
skpos = gaia_fseek (shp->flShp, offset, SEEK_SET);
if (skpos != 0)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (buf, 12, shp->memShp);
else
rd = fread (buf, sizeof (unsigned char), 12, shp->flShp);
if (rd != 12)
goto error;
sz = gaiaImport32 (buf + 4, GAIA_BIG_ENDIAN, shp->endian_arch);
shape = gaiaImport32 (buf + 8, GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (shape == GAIA_SHP_NULL)
{
/* handling a NULL shape */
goto null_shape;
}
else if (shape != shp->Shape)
goto error;
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);
}
if (shape == GAIA_SHP_POINT)
{
/* shape point */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 16, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 16, shp->flShp);
if (rd != 16)
goto error;
x = gaiaImport64 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
{
geom = gaiaAllocGeomCollXYZ ();
gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
geom = gaiaAllocGeomCollXYM ();
gaiaAddPointToGeomCollXYM (geom, x, y, 0.0);
}
else if (shp->EffectiveDims == 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;
geom->Srid = srid;
}
if (shape == GAIA_SHP_POINTZ)
{
/* shape point Z */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
{
/* required by some buggish SHP (e.g. the GDAL/OGR ones) */
if (rd != 24)
goto error;
}
x = gaiaImport64 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
z = gaiaImport64 (shp->BufShp + 16, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (rd == 24)
m = 0.0;
else
m = gaiaImport64 (shp->BufShp + 24, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
{
geom = gaiaAllocGeomCollXYZ ();
gaiaAddPointToGeomCollXYZ (geom, x, y, z);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
geom = gaiaAllocGeomCollXYM ();
gaiaAddPointToGeomCollXYM (geom, x, y, m);
}
else if (shp->EffectiveDims == GAIA_XY_Z_M)
{
geom = gaiaAllocGeomCollXYZM ();
gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
}
else
{
geom = gaiaAllocGeomColl ();
gaiaAddPointToGeomColl (geom, x, y);
}
geom->DeclaredType = GAIA_POINT;
geom->Srid = srid;
}
if (shape == GAIA_SHP_POINTM)
{
/* shape point M */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 24, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 24, shp->flShp);
if (rd != 24)
goto error;
x = gaiaImport64 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
m = gaiaImport64 (shp->BufShp + 16, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
{
geom = gaiaAllocGeomCollXYZ ();
gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
geom = gaiaAllocGeomCollXYM ();
gaiaAddPointToGeomCollXYM (geom, x, y, m);
}
else if (shp->EffectiveDims == GAIA_XY_Z_M)
{
geom = gaiaAllocGeomCollXYZM ();
gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m);
}
else
{
geom = gaiaAllocGeomColl ();
gaiaAddPointToGeomColl (geom, x, y);
}
geom->DeclaredType = GAIA_POINT;
geom->Srid = srid;
}
if (shape == GAIA_SHP_POLYLINE)
{
/* shape polyline */
int extra_check = 0;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
{
if (rd == (sz * 2) - 44)
{
/* sandro 2018-02-17
* it could be some defective SHP badly computing the
* expected record length.
* some unknown software producing defective shapefiles
* of the 2D PolyLine type has been positively identified;
* all record lengths were constantly declaring 4 extra words,
* possibly because the Record Number and the Content Length
* fields were wrongly included into the record length
* calculation.
*/
extra_check = 1;
}
else
goto error;
}
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (extra_check)
{
/* checking the expected buffer size */
int expected = 8 + (n * 4) + (n1 * 16);
if (rd != expected)
goto error;
}
base = 8 + (n * 4);
start = 0;
for (ind = 0; ind < n; ind++)
{
if (ind < (n - 1))
end =
gaiaImport32 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
line = gaiaAllocLinestringXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
line = gaiaAllocLinestringXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
line = gaiaAllocLinestringXYZM (points);
else
line = gaiaAllocLinestring (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == 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 (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_LINESTRING)
geom->DeclaredType = GAIA_LINESTRING;
else
geom->DeclaredType = GAIA_MULTILINESTRING;
geom->Srid = srid;
}
gaiaInsertLinestringInGeomColl (geom, line);
}
}
if (shape == GAIA_SHP_POLYLINEZ)
{
/* shape polyline Z */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
base = 8 + (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 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
line = gaiaAllocLinestringXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
line = gaiaAllocLinestringXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
line = gaiaAllocLinestringXYZM (points);
else
line = gaiaAllocLinestring (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
z = gaiaImport64 (shp->BufShp + baseZ + (iv * 8),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM +
(iv * 8), GAIA_LITTLE_ENDIAN,
shp->endian_arch);
else
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, points, x, y, z);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, points, x, y, m);
}
else if (shp->EffectiveDims == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, points, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, points, x, y);
}
start++;
points++;
}
if (!geom)
{
if (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_LINESTRING)
geom->DeclaredType = GAIA_LINESTRING;
else
geom->DeclaredType = GAIA_MULTILINESTRING;
geom->Srid = srid;
}
gaiaInsertLinestringInGeomColl (geom, line);
}
}
if (shape == GAIA_SHP_POLYLINEM)
{
/* shape polyline M */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
base = 8 + (n * 4);
baseM = base + (n1 * 16) + 16;
start = 0;
for (ind = 0; ind < n; ind++)
{
if (ind < (n - 1))
end =
gaiaImport32 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
line = gaiaAllocLinestringXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
line = gaiaAllocLinestringXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
line = gaiaAllocLinestringXYZM (points);
else
line = gaiaAllocLinestring (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM +
(iv * 8), GAIA_LITTLE_ENDIAN,
shp->endian_arch);
else
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, points, x, y, m);
}
else if (shp->EffectiveDims == 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 (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_LINESTRING)
geom->DeclaredType = GAIA_LINESTRING;
else
geom->DeclaredType = GAIA_MULTILINESTRING;
geom->Srid = srid;
}
gaiaInsertLinestringInGeomColl (geom, line);
}
}
if (shape == GAIA_SHP_POLYGON)
{
/* shape polygon */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
base = 8 + (n * 4);
start = 0;
for (ind = 0; ind < n; ind++)
{
if (ind < (n - 1))
end =
gaiaImport32 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
ring = gaiaAllocRingXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
ring = gaiaAllocRingXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
ring = gaiaAllocRingXYZM (points);
else
ring = gaiaAllocRing (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == 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 (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_POLYGON)
geom->DeclaredType = GAIA_POLYGON;
else
geom->DeclaredType = GAIA_MULTIPOLYGON;
geom->Srid = srid;
shp_build_area (&ringsColl, geom);
}
if (shape == GAIA_SHP_POLYGONZ)
{
/* shape polygon Z */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
base = 8 + (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 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
ring = gaiaAllocRingXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
ring = gaiaAllocRingXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
ring = gaiaAllocRingXYZM (points);
else
ring = gaiaAllocRing (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
z = gaiaImport64 (shp->BufShp + baseZ + (iv * 8),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM +
(iv * 8), GAIA_LITTLE_ENDIAN,
shp->endian_arch);
else
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, points, x, y, z);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, points, x, y, m);
}
else if (shp->EffectiveDims == 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 (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_POLYGON)
geom->DeclaredType = GAIA_POLYGON;
else
geom->DeclaredType = GAIA_MULTIPOLYGON;
geom->Srid = srid;
shp_build_area (&ringsColl, geom);
}
if (shape == GAIA_SHP_POLYGONM)
{
/* shape polygon M */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
base = 8 + (n * 4);
baseM = base + (n1 * 16) + 16;
start = 0;
for (ind = 0; ind < n; ind++)
{
if (ind < (n - 1))
end =
gaiaImport32 (shp->BufShp + 8 + ((ind + 1) * 4),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
end = n1;
points = end - start;
if (shp->EffectiveDims == GAIA_XY_Z)
ring = gaiaAllocRingXYZ (points);
else if (shp->EffectiveDims == GAIA_XY_M)
ring = gaiaAllocRingXYM (points);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
ring = gaiaAllocRingXYZM (points);
else
ring = gaiaAllocRing (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base + (iv * 16) +
8, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM +
(iv * 8), GAIA_LITTLE_ENDIAN,
shp->endian_arch);
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0);
}
else if (shp->EffectiveDims == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, points, x, y, m);
}
else if (shp->EffectiveDims == 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 (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
if (shp->EffectiveType == GAIA_POLYGON)
geom->DeclaredType = GAIA_POLYGON;
else
geom->DeclaredType = GAIA_MULTIPOLYGON;
geom->Srid = srid;
shp_build_area (&ringsColl, geom);
}
if (shape == GAIA_SHP_MULTIPOINT)
{
/* shape multipoint */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
geom->DeclaredType = GAIA_MULTIPOINT;
geom->Srid = srid;
for (iv = 0; iv < n; iv++)
{
x = gaiaImport64 (shp->BufShp + 4 + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 4 + (iv * 16) + 8,
GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (shp->EffectiveDims == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
else if (shp->EffectiveDims == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (geom, x, y, 0.0);
else if (shp->EffectiveDims == 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 */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
baseZ = 4 + (n * 16) + 16;
baseM = baseZ + (n * 8) + 16;
if (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
geom->DeclaredType = GAIA_MULTIPOINT;
geom->Srid = srid;
for (iv = 0; iv < n; iv++)
{
x = gaiaImport64 (shp->BufShp + 4 + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 4 + (iv * 16) + 8,
GAIA_LITTLE_ENDIAN, shp->endian_arch);
z = gaiaImport64 (shp->BufShp + baseZ + (iv * 8),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM + (iv * 8),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (geom, x, y, z);
else if (shp->EffectiveDims == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (geom, x, y, m);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
else
gaiaAddPointToGeomColl (geom, x, y);
}
}
if (shape == GAIA_SHP_MULTIPOINTM)
{
/* shape multipoint M */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32, shp->flShp);
if (rd != 32)
goto error;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), (sz * 2) - 36,
shp->flShp);
if (rd != (sz * 2) - 36)
goto error;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN, shp->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 */
if (sz < min_size)
goto error;
if (sz == max_size)
hasM = 1;
baseM = 4 + (n * 16) + 16;
if (shp->EffectiveDims == GAIA_XY_Z)
geom = gaiaAllocGeomCollXYZ ();
else if (shp->EffectiveDims == GAIA_XY_M)
geom = gaiaAllocGeomCollXYM ();
else if (shp->EffectiveDims == GAIA_XY_Z_M)
geom = gaiaAllocGeomCollXYZM ();
else
geom = gaiaAllocGeomColl ();
geom->DeclaredType = GAIA_MULTIPOINT;
geom->Srid = srid;
for (iv = 0; iv < n; iv++)
{
x = gaiaImport64 (shp->BufShp + 4 + (iv * 16),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
y = gaiaImport64 (shp->BufShp + 4 + (iv * 16) + 8,
GAIA_LITTLE_ENDIAN, shp->endian_arch);
if (hasM)
m = gaiaImport64 (shp->BufShp + baseM + (iv * 8),
GAIA_LITTLE_ENDIAN, shp->endian_arch);
else
m = 0.0;
if (m < SHAPEFILE_NO_DATA)
m = 0.0;
if (shp->EffectiveDims == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0);
else if (shp->EffectiveDims == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (geom, x, y, m);
else if (shp->EffectiveDims == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m);
else
gaiaAddPointToGeomColl (geom, x, y);
}
}
/* setting up the current SHP ENTITY */
null_shape:
gaiaResetDbfEntity (shp->Dbf);
shp->Dbf->RowId = current_row;
shp->Dbf->Geometry = geom;
/* fetching the DBF values */
pFld = shp->Dbf->First;
while (pFld)
{
if (!parseDbfField (shp->BufDbf, shp->IconvObj, pFld, text_dates))
{
char *text = malloc (pFld->Length + 1);
memcpy (text, shp->BufDbf + pFld->Offset + 1, pFld->Length);
text[pFld->Length] = '\0';
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n", text);
free (text);
goto conversion_error;
}
pFld = pFld->Next;
}
if (shp->LastError)
free (shp->LastError);
shp->LastError = NULL;
shp_free_rings (&ringsColl);
return 1;
eof:
if (shp->LastError)
free (shp->LastError);
shp->LastError = NULL;
shp_free_rings (&ringsColl);
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);
shp_free_rings (&ringsColl);
return 0;
dbf_deleted:
if (shp->LastError)
free (shp->LastError);
shp->LastError = NULL;
return -1;
conversion_error:
if (shp->LastError)
free (shp->LastError);
sprintf (errMsg, "Invalid character sequence at DBF line %d", current_row);
len = strlen (errMsg);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, errMsg);
shp_free_rings (&ringsColl);
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);
}
}
}
GAIAGEO_DECLARE int
gaiaWriteShpEntity (gaiaShapefilePtr shp, gaiaDbfListPtr entity)
{
/* trying to write an entity into shapefile */
char dummy[128];
char fmt[16];
int endian_arch = shp->endian_arch;
gaiaDbfFieldPtr fld;
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;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *dynbuf;
char *pUtf8buf;
char utf8buf[2048];
/* writing the DBF record */
memset (shp->BufDbf, '\0', shp->DbfReclen);
*(shp->BufDbf) = ' '; /* in DBF first byte of each row marks for validity or deletion */
fld = entity->First;
while (fld)
{
/* transferring field values */
switch (fld->Type)
{
case 'L':
if (!(fld->Value))
*(shp->BufDbf + fld->Offset) = '?';
else if (fld->Value->Type != GAIA_INT_VALUE)
*(shp->BufDbf + fld->Offset + 1) = '?';
else
{
if (fld->Value->IntValue == 0)
*(shp->BufDbf + fld->Offset + 1) = 'N';
else
*(shp->BufDbf + fld->Offset + 1) = 'Y';
}
break;
case 'D':
memset (shp->BufDbf + fld->Offset + 1, '0', 8);
if (fld->Value)
{
if (fld->Value->Type == GAIA_TEXT_VALUE)
{
if (strlen (fld->Value->TxtValue) == 8)
memcpy (shp->BufDbf + fld->Offset + 1,
fld->Value->TxtValue, 8);
}
}
break;
case 'C':
memset (shp->BufDbf + fld->Offset + 1, ' ', fld->Length);
if (fld->Value)
{
if (fld->Value->Type == GAIA_TEXT_VALUE)
{
len = strlen (fld->Value->TxtValue);
dynbuf = malloc (2048 + len + 1);
strcpy (dynbuf, fld->Value->TxtValue);
if (len > 512)
{
dynbuf[512] = '\0';
len = strlen (dynbuf);
}
utf8len = 2048;
pBuf = dynbuf;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (shp->IconvObj), &pBuf, &len,
&pUtf8buf, &utf8len) == (size_t) (-1))
{
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n",
dynbuf);
free (dynbuf);
goto conversion_error;
}
memcpy (dynbuf, utf8buf, 2048 - utf8len);
dynbuf[2048 - utf8len] = '\0';
if (strlen (dynbuf) < fld->Length)
memcpy (shp->BufDbf + fld->Offset + 1, dynbuf,
strlen (dynbuf));
else
memcpy (shp->BufDbf + fld->Offset + 1, dynbuf,
fld->Length);
free (dynbuf);
}
}
break;
case 'N':
memset (shp->BufDbf + fld->Offset + 1, '\0', fld->Length);
if (fld->Value)
{
if (fld->Value->Type == GAIA_INT_VALUE)
{
sprintf (dummy, FRMT64, fld->Value->IntValue);
if (strlen (dummy) <= fld->Length)
memcpy (shp->BufDbf + fld->Offset + 1,
dummy, strlen (dummy));
}
if (fld->Value->Type == GAIA_DOUBLE_VALUE)
{
sprintf (fmt, "%%1.%df", fld->Decimals);
sprintf (dummy, fmt, fld->Value->DblValue);
if (strlen (dummy) <= fld->Length)
memcpy (shp->BufDbf + fld->Offset + 1,
dummy, strlen (dummy));
}
}
break;
};
fld = fld->Next;
}
if (!(entity->Geometry))
{
/* exporting a NULL Shape */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_NULL, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = NULL */
fwrite (shp->BufShp, 1, 12, shp->flShp);
(shp->ShpSize) += 6; /* updating current SHP file position [in 16 bits words !!!] */
}
else
{
/* updates the shapefile main MBR-BBOX */
gaiaMbrGeometry (entity->Geometry);
if (entity->Geometry->MinX < shp->MinX)
shp->MinX = entity->Geometry->MinX;
if (entity->Geometry->MaxX > shp->MaxX)
shp->MaxX = entity->Geometry->MaxX;
if (entity->Geometry->MinY < shp->MinY)
shp->MinY = entity->Geometry->MinY;
if (entity->Geometry->MaxY > shp->MaxY)
shp->MaxY = entity->Geometry->MaxY;
if (shp->Shape == GAIA_SHP_POINT)
{
/* this one is expected to be a POINT */
gaiaPointPtr pt = entity->Geometry->FirstPoint;
if (!pt)
{
strcpy (dummy,
"a POINT is expected, but there is no POINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
/* inserting POINT entity into SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, 10, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */
/* inserting POINT into SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, 10, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT */
gaiaExport64 (shp->BufShp + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
gaiaExport64 (shp->BufShp + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
fwrite (shp->BufShp, 1, 28, shp->flShp);
(shp->ShpSize) += 14; /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_POINTZ)
{
/* this one is expected to be a POINT Z */
gaiaPointPtr pt = entity->Geometry->FirstPoint;
if (!pt)
{
strcpy (dummy,
"a POINT is expected, but there is no POINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
/* inserting POINT Z entity into SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, 18, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */
/* inserting POINT into SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, 18, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT Z */
gaiaExport64 (shp->BufShp + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
gaiaExport64 (shp->BufShp + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
gaiaExport64 (shp->BufShp + 28, pt->Z, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Z coordinate */
gaiaExport64 (shp->BufShp + 36, pt->M, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */
fwrite (shp->BufShp, 1, 44, shp->flShp);
(shp->ShpSize) += 22; /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_POINTM)
{
/* this one is expected to be a POINT M */
gaiaPointPtr pt = entity->Geometry->FirstPoint;
if (!pt)
{
strcpy (dummy,
"a POINT is expected, but there is no POINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
/* inserting POINT entity into SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, 14, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */
/* inserting POINT into SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, 14, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT M */
gaiaExport64 (shp->BufShp + 12, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */
gaiaExport64 (shp->BufShp + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */
gaiaExport64 (shp->BufShp + 28, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */
fwrite (shp->BufShp, 1, 36, shp->flShp);
(shp->ShpSize) += 18; /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_POLYLINE)
{
/* this one is expected to be a LINESTRING / MULTILINESTRING */
gaiaLinestringPtr line;
tot_ln = 0;
tot_v = 0;
line = entity->Geometry->FirstLinestring;
while (line)
{
/* computes # lines and total # points */
tot_v += line->Points;
tot_ln++;
line = line->Next;
}
if (!tot_ln)
{
strcpy (dummy,
"a LINESTRING is expected, but there is no LINESTRING in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 22 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting LINESTRING or MULTILINESTRING in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting LINESTRING or MULTILINESTRING in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYLINE, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
line = entity->Geometry->FirstLinestring;
while (line)
{
/* exports start point index for each line */
gaiaExport32 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += line->Points;
ix += 4;
line = line->Next;
}
line = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
}
line = line->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_POLYLINEZ)
{
/* this one is expected to be a LINESTRING / MULTILINESTRING Z */
gaiaLinestringPtr line;
gaiaZRangeGeometry (entity->Geometry, &minZ, &maxZ);
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_ln = 0;
tot_v = 0;
line = entity->Geometry->FirstLinestring;
while (line)
{
/* computes # lines and total # points */
tot_v += line->Points;
tot_ln++;
line = line->Next;
}
if (!tot_ln)
{
strcpy (dummy,
"a LINESTRING is expected, but there is no LINESTRING in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
hasM = 0;
if (shp->EffectiveDims == GAIA_XY_M
|| shp->EffectiveDims == GAIA_XY_Z_M)
hasM = 1;
if (hasM)
this_size = 38 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */
else
this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting LINESTRING or MULTILINESTRING in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting LINESTRING or MULTILINESTRING in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYLINEZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE Z */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
line = entity->Geometry->FirstLinestring;
while (line)
{
/* exports start point index for each line */
gaiaExport32 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += line->Points;
ix += 4;
line = line->Next;
}
line = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
}
line = line->Next;
}
/* exporting the Z-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
line = entity->Geometry->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 (shp->BufShp + ix, z,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
}
line = line->Next;
}
if (hasM)
{
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
line = entity->Geometry->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 (shp->BufShp + ix, m,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
line = line->Next;
}
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_POLYLINEM)
{
/* this one is expected to be a LINESTRING / MULTILINESTRING M */
gaiaLinestringPtr line;
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_ln = 0;
tot_v = 0;
line = entity->Geometry->FirstLinestring;
while (line)
{
/* computes # lines and total # points */
tot_v += line->Points;
tot_ln++;
line = line->Next;
}
if (!tot_ln)
{
strcpy (dummy,
"a LINESTRING is expected, but there is no LINESTRING in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting LINESTRING or MULTILINESTRING in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting LINESTRING or MULTILINESTRING in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYLINEM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE M */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
line = entity->Geometry->FirstLinestring;
while (line)
{
/* exports start point index for each line */
gaiaExport32 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += line->Points;
ix += 4;
line = line->Next;
}
line = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
}
line = line->Next;
}
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
line = entity->Geometry->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 (shp->BufShp + ix, m,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
}
line = line->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == 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 = entity->Geometry->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;
}
if (!tot_ln)
{
strcpy (dummy,
"a POLYGON is expected, but there is no POLYGON in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 22 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting POLYGON or MULTIPOLYGON in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting POLYGON or MULTIPOLYGON in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYGON, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
polyg = entity->Geometry->FirstPolygon;
while (polyg)
{
/* exports start point index for each line */
ring = polyg->Exterior; /* this one is the exterior ring */
gaiaExport32 (shp->BufShp + 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 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += ring->Points;
ix += 4;
}
polyg = polyg->Next;
}
polyg = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + 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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2);
}
if (shp->Shape == GAIA_SHP_POLYGONZ)
{
/* this one is expected to be a POLYGON or a MULTIPOLYGON Z */
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
int ib;
gaiaZRangeGeometry (entity->Geometry, &minZ, &maxZ);
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_ln = 0;
tot_v = 0;
polyg = entity->Geometry->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;
}
if (!tot_ln)
{
strcpy (dummy,
"a POLYGON is expected, but there is no POLYGON in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
hasM = 0;
if (shp->EffectiveDims == GAIA_XY_M
|| shp->EffectiveDims == GAIA_XY_Z_M)
hasM = 1;
if (hasM)
this_size = 38 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */
else
this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting POLYGON or MULTIPOLYGON in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting POLYGON or MULTIPOLYGON in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYGONZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON Z */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
polyg = entity->Geometry->FirstPolygon;
while (polyg)
{
/* exports start point index for each line */
ring = polyg->Exterior; /* this one is the exterior ring */
gaiaExport32 (shp->BufShp + 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 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += ring->Points;
ix += 4;
}
polyg = polyg->Next;
}
polyg = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + 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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
/* exporting the Z-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
polyg = entity->Geometry->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 (shp->BufShp + 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 (shp->BufShp + ix, z,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
if (hasM)
{
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
polyg = entity->Geometry->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 (shp->BufShp + 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 (shp->BufShp + ix, m,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2);
}
if (shp->Shape == GAIA_SHP_POLYGONM)
{
/* this one is expected to be a POLYGON or a MULTIPOLYGON M */
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
int ib;
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_ln = 0;
tot_v = 0;
polyg = entity->Geometry->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;
}
if (!tot_ln)
{
strcpy (dummy,
"a POLYGON is expected, but there is no POLYGON in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting POLYGON or MULTIPOLYGON in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting POLYGON or MULTIPOLYGON in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_POLYGONM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON M */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */
gaiaExport32 (shp->BufShp + 48, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
tot_v = 0; /* resets points counter */
ix = 52; /* sets current buffer offset */
polyg = entity->Geometry->FirstPolygon;
while (polyg)
{
/* exports start point index for each line */
ring = polyg->Exterior; /* this one is the exterior ring */
gaiaExport32 (shp->BufShp + 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 (shp->BufShp + ix, tot_v,
GAIA_LITTLE_ENDIAN, endian_arch);
tot_v += ring->Points;
ix += 4;
}
polyg = polyg->Next;
}
polyg = entity->Geometry->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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + 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 (shp->BufShp + ix, x,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, y,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
polyg = entity->Geometry->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 (shp->BufShp + 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 (shp->BufShp + ix, m,
GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
}
}
polyg = polyg->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2);
}
if (shp->Shape == GAIA_SHP_MULTIPOINT)
{
/* this one is expected to be a MULTIPOINT */
gaiaPointPtr pt;
tot_pts = 0;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* computes # points */
tot_pts++;
pt = pt->Next;
}
if (!tot_pts)
{
strcpy (dummy,
"a MULTIPOINT is expected, but there is no POINT/MULTIPOINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 20 + (tot_pts * 8); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting MULTIPOINT in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting MULTIPOINT in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_MULTIPOINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
ix = 48; /* sets current buffer offset */
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports each point */
gaiaExport64 (shp->BufShp + ix, pt->X,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, pt->Y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_MULTIPOINTZ)
{
/* this one is expected to be a MULTIPOINT Z */
gaiaPointPtr pt;
gaiaZRangeGeometry (entity->Geometry, &minZ, &maxZ);
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_pts = 0;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* computes # points */
tot_pts++;
pt = pt->Next;
}
if (!tot_pts)
{
strcpy (dummy,
"a MULTIPOINT is expected, but there is no POINT/MULTIPOINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
hasM = 0;
if (shp->EffectiveDims == GAIA_XY_M
|| shp->EffectiveDims == GAIA_XY_Z_M)
hasM = 1;
if (hasM)
this_size = 36 + (tot_pts * 16); /* size [in 16 bits words !!!] ZM */
else
this_size = 28 + (tot_pts * 12); /* size [in 16 bits words !!!] Z-only */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting MULTIPOINT in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting MULTIPOINT in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_MULTIPOINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT Z */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
ix = 48; /* sets current buffer offset */
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports each point */
gaiaExport64 (shp->BufShp + ix, pt->X,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, pt->Y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
/* exporting the Z-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxZ, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports Z-values */
gaiaExport64 (shp->BufShp + ix, pt->Z,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
if (hasM)
{
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports M-values */
gaiaExport64 (shp->BufShp + ix, pt->M,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
if (shp->Shape == GAIA_SHP_MULTIPOINTM)
{
/* this one is expected to be a MULTIPOINT M */
gaiaPointPtr pt;
gaiaMRangeGeometry (entity->Geometry, &minM, &maxM);
tot_pts = 0;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* computes # points */
tot_pts++;
pt = pt->Next;
}
if (!tot_pts)
{
strcpy (dummy,
"a MULTIPOINT is expected, but there is no POINT/MULTIPOINT in geometry");
if (shp->LastError)
free (shp->LastError);
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
this_size = 28 + (tot_pts * 12); /* size [in 16 bits words !!!] for this SHP entity */
if ((this_size * 2) + 1024 > shp->ShpBfsz)
{
/* current buffer is too small; we need to allocate a bigger one */
free (shp->BufShp);
shp->ShpBfsz = (this_size * 2) + 1024;
shp->BufShp = malloc (shp->ShpBfsz);
}
/* inserting MULTIPOINT in SHX file */
gaiaExport32 (shp->BufShp, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */
fwrite (shp->BufShp, 1, 8, shp->flShx);
(shp->ShxSize) += 4;
/* inserting MULTIPOINT in SHP file */
gaiaExport32 (shp->BufShp, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */
gaiaExport32 (shp->BufShp + 4, this_size, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */
gaiaExport32 (shp->BufShp + 8, GAIA_SHP_MULTIPOINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT M */
gaiaExport64 (shp->BufShp + 12, entity->Geometry->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */
gaiaExport64 (shp->BufShp + 20, entity->Geometry->MinY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 28, entity->Geometry->MaxX,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (shp->BufShp + 36, entity->Geometry->MaxY,
GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport32 (shp->BufShp + 44, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */
ix = 48; /* sets current buffer offset */
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports each point */
gaiaExport64 (shp->BufShp + ix, pt->X,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, pt->Y,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
/* exporting the M-range [min/max] */
gaiaExport64 (shp->BufShp + ix, minM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
gaiaExport64 (shp->BufShp + ix, maxM, GAIA_LITTLE_ENDIAN,
endian_arch);
ix += 8;
pt = entity->Geometry->FirstPoint;
while (pt)
{
/* exports M-values */
gaiaExport64 (shp->BufShp + ix, pt->M,
GAIA_LITTLE_ENDIAN, endian_arch);
ix += 8;
pt = pt->Next;
}
fwrite (shp->BufShp, 1, ix, shp->flShp);
(shp->ShpSize) += (ix / 2); /* updating current SHP file position [in 16 bits words !!!] */
}
}
/* inserting entity in DBF file */
fwrite (shp->BufDbf, 1, shp->DbfReclen, shp->flDbf);
(shp->DbfRecno)++;
return 1;
conversion_error:
if (shp->LastError)
free (shp->LastError);
sprintf (dummy, "Invalid character sequence");
len = strlen (dummy);
shp->LastError = malloc (len + 1);
strcpy (shp->LastError, dummy);
return 0;
}
GAIAGEO_DECLARE void
gaiaFlushShpHeaders (gaiaShapefilePtr shp)
{
/* updates the various file headers */
FILE *fl_shp = shp->flShp;
FILE *fl_shx = shp->flShx;
FILE *fl_dbf = shp->flDbf;
int shp_size = shp->ShpSize;
int shx_size = shp->ShxSize;
int dbf_size = shp->DbfSize;
int dbf_reclen = shp->DbfReclen;
int dbf_recno = shp->DbfRecno;
int endian_arch = shp->endian_arch;
double minx = shp->MinX;
double miny = shp->MinY;
double maxx = shp->MaxX;
double maxy = shp->MaxY;
unsigned char *buf_shp = shp->BufShp;
/* writing the SHP file header */
gaia_fseek (fl_shp, 0, SEEK_SET); /* repositioning at SHP file start */
gaiaExport32 (buf_shp, 9994, GAIA_BIG_ENDIAN, endian_arch); /* SHP magic number */
gaiaExport32 (buf_shp + 4, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 8, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 12, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 16, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 20, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 24, shp_size, GAIA_BIG_ENDIAN, endian_arch); /* SHP file size - measured in 16 bits words !!! */
gaiaExport32 (buf_shp + 28, 1000, GAIA_LITTLE_ENDIAN, endian_arch); /* version */
gaiaExport32 (buf_shp + 32, shp->Shape, GAIA_LITTLE_ENDIAN, endian_arch); /* ESRI shape */
gaiaExport64 (buf_shp + 36, minx, GAIA_LITTLE_ENDIAN, endian_arch); /* the MBR/BBOX for the whole shapefile */
gaiaExport64 (buf_shp + 44, miny, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 52, maxx, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 60, maxy, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 68, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 76, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 84, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 92, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
fwrite (buf_shp, 1, 100, fl_shp);
/* writing the SHX file header */
gaia_fseek (fl_shx, 0, SEEK_SET); /* repositioning at SHX file start */
gaiaExport32 (buf_shp, 9994, GAIA_BIG_ENDIAN, endian_arch); /* SHP magic number */
gaiaExport32 (buf_shp + 4, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 8, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 12, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 16, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 20, 0, GAIA_BIG_ENDIAN, endian_arch);
gaiaExport32 (buf_shp + 24, shx_size, GAIA_BIG_ENDIAN, endian_arch); /* SHXfile size - measured in 16 bits words !!! */
gaiaExport32 (buf_shp + 28, 1000, GAIA_LITTLE_ENDIAN, endian_arch); /* version */
gaiaExport32 (buf_shp + 32, shp->Shape, GAIA_LITTLE_ENDIAN, endian_arch); /* ESRI shape */
gaiaExport64 (buf_shp + 36, minx, GAIA_LITTLE_ENDIAN, endian_arch); /* the MBR for the whole shapefile */
gaiaExport64 (buf_shp + 44, miny, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 52, maxx, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 60, maxy, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 68, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 76, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 84, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaExport64 (buf_shp + 92, 0.0, GAIA_LITTLE_ENDIAN, endian_arch);
fwrite (buf_shp, 1, 100, fl_shx);
/* writing the DBF file header */
*buf_shp = 0x1a; /* DBF - this is theEOF marker */
fwrite (buf_shp, 1, 1, fl_dbf);
gaia_fseek (fl_dbf, 0, SEEK_SET); /* repositioning at DBF file start */
memset (buf_shp, '\0', 32);
*buf_shp = 0x03; /* DBF magic number */
*(buf_shp + 1) = 1; /* this is supposed to be the last update date [Year, Month, Day], but we ignore it at all */
*(buf_shp + 2) = 1;
*(buf_shp + 3) = 1;
gaiaExport32 (buf_shp + 4, dbf_recno, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # records in this DBF */
gaiaExport16 (buf_shp + 8, (short) dbf_size, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the file header size */
gaiaExport16 (buf_shp + 10, (short) dbf_reclen, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the record length */
fwrite (buf_shp, 1, 32, fl_dbf);
}
GAIAGEO_DECLARE void
gaiaShpAnalyze (gaiaShapefilePtr shp)
{
/* analyzing the SHP content, in order to detect if there are LINESTRINGS or MULTILINESTRINGS
/ the same check is needed in order to detect if there are POLYGONS or MULTIPOLYGONS
*/
unsigned char buf[512];
int rd;
int skpos;
gaia_off_t offset;
int off_shp;
int sz;
int shape;
int points;
int n;
int n1;
int base;
int start;
int end;
int iv;
int ind;
double x;
double y;
int polygons;
int ZM_size;
int multi = 0;
int hasM = 0;
int current_row = 0;
gaiaRingPtr ring = NULL;
while (1)
{
/* positioning and reading the SHX file */
offset = 100 + ((gaia_off_t) current_row * (gaia_off_t) 8); /* 100 bytes for the header + current row displacement; each SHX row = 8 bytes */
if (shp->memShx != NULL)
skpos = gaiaMemFseek (shp->memShx, offset);
else
skpos = gaia_fseek (shp->flShx, offset, SEEK_SET);
if (skpos != 0)
goto exit;
if (shp->memShx != NULL)
rd = gaiaMemRead (buf, 8, shp->memShx);
else
rd = fread (buf, sizeof (unsigned char), 8, shp->flShx);
if (rd != 8)
goto exit;
off_shp = gaiaImport32 (buf, GAIA_BIG_ENDIAN, shp->endian_arch);
/* positioning and reading corresponding SHP entity - geometry */
offset = (gaia_off_t) off_shp *2;
if (shp->memShp != NULL)
skpos = gaiaMemFseek (shp->memShp, offset);
else
skpos = gaia_fseek (shp->flShp, offset, SEEK_SET);
if (skpos != 0)
goto exit;
if (shp->memShp != NULL)
rd = gaiaMemRead (buf, 12, shp->memShp);
else
rd = fread (buf, sizeof (unsigned char), 12, shp->flShp);
if (rd != 12)
goto exit;
sz = gaiaImport32 (buf + 4, GAIA_BIG_ENDIAN, shp->endian_arch);
shape = gaiaImport32 (buf + 8, GAIA_LITTLE_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);
}
if (shape == GAIA_SHP_POLYLINE || shape == GAIA_SHP_POLYLINEZ
|| shape == GAIA_SHP_POLYLINEM)
{
/* shape polyline */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32,
shp->flShp);
if (rd != 32)
goto exit;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char),
(sz * 2) - 36, shp->flShp);
if (rd != (sz * 2) - 36)
goto exit;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
if (n > 1)
multi++;
if (shape == GAIA_SHP_POLYLINEZ)
{
ZM_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */
if (sz == ZM_size)
hasM = 1;
}
}
if (shape == GAIA_SHP_POLYGON || shape == GAIA_SHP_POLYGONZ
|| shape == GAIA_SHP_POLYGONM)
{
/* shape polygon */
struct shp_ring_item *pExt;
struct shp_ring_collection ringsColl;
/* initializing the RING collection */
ringsColl.First = NULL;
ringsColl.Last = NULL;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32,
shp->flShp);
if (rd != 32)
goto exit;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char),
(sz * 2) - 36, shp->flShp);
if (rd != (sz * 2) - 36)
goto exit;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
n1 = gaiaImport32 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
base = 8 + (n * 4);
start = 0;
for (ind = 0; ind < n; ind++)
{
if (ind < (n - 1))
end =
gaiaImport32 (shp->BufShp + 8 +
((ind + 1) * 4),
GAIA_LITTLE_ENDIAN,
shp->endian_arch);
else
end = n1;
points = end - start;
ring = gaiaAllocRing (points);
points = 0;
for (iv = start; iv < end; iv++)
{
x = gaiaImport64 (shp->BufShp + base +
(iv * 16), GAIA_LITTLE_ENDIAN,
shp->endian_arch);
y = gaiaImport64 (shp->BufShp + base +
(iv * 16) + 8,
GAIA_LITTLE_ENDIAN,
shp->endian_arch);
gaiaSetPoint (ring->Coords, points, x, y);
start++;
points++;
}
shp_add_ring (&ringsColl, ring);
ring = NULL;
}
shp_arrange_rings (&ringsColl);
pExt = ringsColl.First;
polygons = 0;
while (pExt != NULL)
{
if (pExt->IsExterior)
polygons++;
pExt = pExt->Next;
}
shp_free_rings (&ringsColl);
if (polygons > 1)
multi++;
if (shape == GAIA_SHP_POLYGONZ)
{
ZM_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */
if (sz == ZM_size)
hasM = 1;
}
}
if (shape == GAIA_SHP_MULTIPOINTZ)
{
/* shape multipoint Z */
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, 32, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char), 32,
shp->flShp);
if (rd != 32)
goto exit;
if (shp->memShp != NULL)
rd = gaiaMemRead (shp->BufShp, (sz * 2) - 36, shp->memShp);
else
rd = fread (shp->BufShp, sizeof (unsigned char),
(sz * 2) - 36, shp->flShp);
if (rd != (sz * 2) - 36)
goto exit;
n = gaiaImport32 (shp->BufShp, GAIA_LITTLE_ENDIAN,
shp->endian_arch);
ZM_size = 38 + (n * 16); /* size [in 16 bits words !!!] ZM */
if (sz == ZM_size)
hasM = 1;
}
current_row++;
}
exit:
if (ring)
gaiaFreeRing (ring);
if (shp->LastError)
free (shp->LastError);
shp->LastError = NULL;
/* setting the EffectiveType, as determined by this analysis */
if (shp->Shape == GAIA_SHP_POLYLINE || shp->Shape == GAIA_SHP_POLYLINEZ
|| shp->Shape == GAIA_SHP_POLYLINEM)
{
/* SHAPE polyline */
if (multi)
shp->EffectiveType = GAIA_MULTILINESTRING;
else
shp->EffectiveType = GAIA_LINESTRING;
}
if (shp->Shape == GAIA_SHP_POLYGON || shp->Shape == GAIA_SHP_POLYGONZ
|| shp->Shape == GAIA_SHP_POLYGONM)
{
/* SHAPE polygon */
if (multi)
shp->EffectiveType = GAIA_MULTIPOLYGON;
else
shp->EffectiveType = GAIA_POLYGON;
}
if (shp->Shape == GAIA_SHP_POLYLINEZ || shp->Shape == GAIA_SHP_POLYGONZ
|| shp->Shape == GAIA_SHP_MULTIPOINTZ)
{
if (hasM)
shp->EffectiveDims = GAIA_XY_Z_M;
else
shp->EffectiveDims = GAIA_XY_Z;
}
}
GAIAGEO_DECLARE gaiaDbfPtr
gaiaAllocDbf ()
{
/* allocates and initializes the DBF object */
gaiaDbfPtr dbf = malloc (sizeof (gaiaDbf));
dbf->endian_arch = 1;
dbf->Path = NULL;
dbf->flDbf = NULL;
dbf->memDbf = NULL;
dbf->Dbf = NULL;
dbf->BufDbf = NULL;
dbf->DbfHdsz = 0;
dbf->DbfReclen = 0;
dbf->DbfSize = 0;
dbf->DbfRecno = 0;
dbf->Valid = 0;
dbf->IconvObj = NULL;
dbf->LastError = NULL;
return dbf;
}
GAIAGEO_DECLARE void
gaiaFreeDbf (gaiaDbfPtr dbf)
{
/* frees all memory allocations related to the DBF object */
if (dbf->Path)
free (dbf->Path);
if (dbf->flDbf)
fclose (dbf->flDbf);
if (dbf->Dbf)
gaiaFreeDbfList (dbf->Dbf);
if (dbf->BufDbf)
free (dbf->BufDbf);
if (dbf->IconvObj)
iconv_close ((iconv_t) dbf->IconvObj);
if (dbf->LastError)
free (dbf->LastError);
free (dbf);
}
GAIAGEO_DECLARE void
gaiaOpenDbfRead (gaiaDbfPtr dbf, const char *path, const char *charFrom,
const char *charTo)
{
/* trying to open the DBF and initial checkings */
FILE *fl_dbf = NULL;
int rd;
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];
iconv_t iconv_ret;
char utf8buf[2048];
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int endian_arch = gaiaEndianArch ();
gaiaDbfListPtr dbf_list = NULL;
if (charFrom && charTo)
{
iconv_ret = iconv_open (charTo, charFrom);
if (iconv_ret == (iconv_t) (-1))
{
sprintf (errMsg,
"conversion from '%s' to '%s' not available\n",
charFrom, charTo);
goto unsupported_conversion;
}
dbf->IconvObj = iconv_ret;
}
else
{
sprintf (errMsg, "a NULL charset-name was passed\n");
goto unsupported_conversion;
}
if (dbf->flDbf != NULL)
{
sprintf (errMsg, "attempting to reopen an already opened DBF\n");
goto unsupported_conversion;
}
if (dbf->memDbf == NULL)
{
#ifdef _WIN32
fl_dbf = gaia_win_fopen (path, "rb");
#else
fl_dbf = fopen (path, "rb");
#endif
if (!fl_dbf)
{
sys_err = strerror (errno);
sprintf (errMsg, "unable to open '%s' for reading: %s", path,
sys_err);
goto no_file;
}
}
/* reading DBF file header */
if (dbf->memDbf != NULL)
rd = gaiaMemRead (bf, 32, dbf->memDbf);
else
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 */
if ((dbf_size - ind) < 32)
{
/* some odd DBF could contain some unexpected extra-padding */
int extra = dbf_size - ind;
if (dbf->memDbf != NULL)
rd = gaiaMemRead (bf, extra, dbf->memDbf);
else
rd = fread (bf, sizeof (unsigned char), extra, fl_dbf);
if (rd != extra)
goto error;
/* ignoring the extra-padding */
break;
}
if (dbf->memDbf != NULL)
rd = gaiaMemRead (bf, 32, dbf->memDbf);
else
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);
spatialite_e
("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';
len = strlen ((char *) field_name);
utf8len = 2048;
pBuf = (char *) field_name;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (dbf->IconvObj), &pBuf, &len, &pUtf8buf,
&utf8len) == (size_t) (-1))
{
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n",
field_name);
goto conversion_error;
}
memcpy (field_name, utf8buf, 2048 - utf8len);
field_name[2048 - utf8len] = '\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);
dbf->Path = malloc (len + 1);
strcpy (dbf->Path, path);
dbf->flDbf = fl_dbf;
dbf->Dbf = dbf_list;
/* allocating DBF buffer */
dbf->BufDbf = malloc (sizeof (unsigned char) * dbf_reclen);
dbf->DbfHdsz = dbf_size + 1;
dbf->DbfReclen = dbf_reclen;
dbf->Valid = 1;
dbf->endian_arch = endian_arch;
return;
unsupported_conversion:
/* illegal charset */
if (dbf->LastError)
free (dbf->LastError);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
return;
no_file:
/* the DBF file can't be accessed */
if (dbf->LastError)
free (dbf->LastError);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
if (fl_dbf)
fclose (fl_dbf);
return;
error:
/* the DBF is invalid or corrupted */
if (dbf->LastError)
free (dbf->LastError);
sprintf (errMsg, "'%s' is corrupted / has invalid format", path);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
gaiaFreeDbfList (dbf_list);
fclose (fl_dbf);
return;
dbf_bad_magic:
/* the DBF has an invalid magic number */
if (dbf->LastError)
free (dbf->LastError);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
gaiaFreeDbfList (dbf_list);
fclose (fl_dbf);
return;
illegal_dbf:
/* the DBF-file contains unsupported data types */
if (dbf->LastError)
free (dbf->LastError);
sprintf (errMsg, "'%s' contains unsupported data types", path);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
gaiaFreeDbfList (dbf_list);
if (fl_dbf)
fclose (fl_dbf);
return;
conversion_error:
/* libiconv error */
if (dbf->LastError)
free (dbf->LastError);
sprintf (errMsg, "'%s.dbf' field name: invalid character sequence", path);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
gaiaFreeDbfList (dbf_list);
if (fl_dbf)
fclose (fl_dbf);
return;
}
GAIAGEO_DECLARE void
gaiaOpenDbfWrite (gaiaDbfPtr dbf, const char *path, const char *charFrom,
const char *charTo)
{
/* trying to create the DBF file */
gaiaOpenDbfWriteEx (dbf, path, charFrom, charTo,
GAIA_DBF_COLNAME_CASE_IGNORE);
}
GAIAGEO_DECLARE void
gaiaOpenDbfWriteEx (gaiaDbfPtr dbf, const char *path, const char *charFrom,
const char *charTo, int colname_case)
{
/* trying to create the DBF file */
FILE *fl_dbf = NULL;
unsigned char bf[1024];
unsigned char *dbf_buf = NULL;
gaiaDbfFieldPtr fld;
char *sys_err;
char errMsg[1024];
short dbf_reclen = 0;
unsigned short dbf_size = 0;
iconv_t iconv_ret;
char buf[2048];
char utf8buf[2048];
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
int defaultId = 1;
struct auxdbf_list *auxdbf = NULL;
if (charFrom && charTo)
{
iconv_ret = iconv_open (charTo, charFrom);
if (iconv_ret == (iconv_t) (-1))
{
sprintf (errMsg, "conversion from '%s' to '%s' not available\n",
charFrom, charTo);
goto unsupported_conversion;
}
dbf->IconvObj = iconv_ret;
}
else
{
sprintf (errMsg, "a NULL charset-name was passed\n");
goto unsupported_conversion;
}
if (dbf->flDbf != NULL)
{
sprintf (errMsg, "attempting to reopen an already opened DBF file\n");
goto unsupported_conversion;
}
/* trying to open the DBF file */
#ifdef _WIN32
fl_dbf = gaia_win_fopen (path, "wb");
#else
fl_dbf = fopen (path, "wb");
#endif
if (!fl_dbf)
{
sys_err = strerror (errno);
sprintf (errMsg, "unable to open '%s' for writing: %s", path,
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->Dbf->First;
while (fld)
{
/* computing the DBF record length */
dbf_reclen += fld->Length;
fld = fld->Next;
}
dbf_buf = malloc (dbf_reclen);
/* writing the DBF file header */
memset (bf, '\0', 32);
fwrite (bf, 1, 32, fl_dbf);
dbf_size = 32; /* note: DBF counts sizes in bytes */
auxdbf = alloc_auxdbf (dbf->Dbf);
fld = dbf->Dbf->First;
while (fld)
{
/* exporting DBF Fields specifications */
memset (bf, 0, 32);
if (strlen (fld->Name) > 10)
{
/* long name: attempting to safely truncate */
truncate_long_name (auxdbf, fld);
}
strcpy (buf, fld->Name);
len = strlen (buf);
utf8len = 2048;
pBuf = buf;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (dbf->IconvObj), &pBuf, &len, &pUtf8buf,
&utf8len) == (size_t) (-1))
sprintf (buf, "FLD#%d", defaultId++);
else
{
memcpy (buf, utf8buf, 2048 - utf8len);
buf[2048 - utf8len] = '\0';
if (strlen (buf) > 10)
sprintf (buf, "FLD#%d", defaultId++);
}
convert_dbf_colname_case (buf, colname_case);
memcpy (bf, buf, strlen (buf));
*(bf + 11) = fld->Type;
*(bf + 16) = fld->Length;
*(bf + 17) = fld->Decimals;
fwrite (bf, 1, 32, fl_dbf);
dbf_size += 32;
fld = fld->Next;
}
free_auxdbf (auxdbf);
fwrite ("\r", 1, 1, fl_dbf); /* this one is a special DBF delimiter that closes file header */
dbf_size++;
dbf->Valid = 1;
dbf->flDbf = fl_dbf;
dbf->BufDbf = dbf_buf;
dbf->DbfHdsz = dbf_size + 1;
dbf->DbfReclen = dbf_reclen;
dbf->DbfSize = dbf_size;
dbf->DbfRecno = 0;
return;
unsupported_conversion:
/* illegal charset */
if (dbf->LastError)
free (dbf->LastError);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
return;
no_file:
/* the DBF file can't be created/opened */
if (dbf->LastError)
free (dbf->LastError);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
if (dbf_buf)
free (dbf_buf);
if (fl_dbf)
fclose (fl_dbf);
return;
}
GAIAGEO_DECLARE int
gaiaWriteDbfEntity (gaiaDbfPtr dbf, gaiaDbfListPtr entity)
{
/* trying to write an entity into some DBF file */
char dummy[128];
char fmt[16];
gaiaDbfFieldPtr fld;
#if !defined(__MINGW32__) && defined(_WIN32)
const char *pBuf;
#else /* not WIN32 */
char *pBuf;
#endif
size_t len;
size_t utf8len;
char *pUtf8buf;
char *dynbuf;
char utf8buf[2048];
/* writing the DBF record */
memset (dbf->BufDbf, '\0', dbf->DbfReclen);
*(dbf->BufDbf) = ' '; /* in DBF first byte of each row marks for validity or deletion */
fld = entity->First;
while (fld)
{
/* transferring field values */
switch (fld->Type)
{
case 'L':
if (!(fld->Value))
*(dbf->BufDbf + fld->Offset) = '?';
else if (fld->Value->Type != GAIA_INT_VALUE)
*(dbf->BufDbf + fld->Offset + 1) = '?';
else
{
if (fld->Value->IntValue == 0)
*(dbf->BufDbf + fld->Offset + 1) = 'N';
else
*(dbf->BufDbf + fld->Offset + 1) = 'Y';
}
break;
case 'D':
memset (dbf->BufDbf + fld->Offset + 1, '0', 8);
if (fld->Value)
{
if (fld->Value->Type == GAIA_TEXT_VALUE)
{
if (strlen (fld->Value->TxtValue) == 8)
memcpy (dbf->BufDbf + fld->Offset + 1,
fld->Value->TxtValue, 8);
}
}
break;
case 'C':
memset (dbf->BufDbf + fld->Offset + 1, ' ', fld->Length);
if (fld->Value)
{
if (fld->Value->Type == GAIA_TEXT_VALUE)
{
len = strlen (fld->Value->TxtValue);
dynbuf = malloc (len + 1);
strcpy (dynbuf, fld->Value->TxtValue);
if (len > 512)
{
dynbuf[512] = '\0';
len = strlen (dynbuf);
}
utf8len = 2048;
pBuf = dynbuf;
pUtf8buf = utf8buf;
if (iconv
((iconv_t) (dbf->IconvObj), &pBuf, &len,
&pUtf8buf, &utf8len) == (size_t) (-1))
{
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n",
dynbuf);
free (dynbuf);
goto conversion_error;
}
memcpy (dynbuf, utf8buf, 2048 - utf8len);
dynbuf[2048 - utf8len] = '\0';
if (strlen (dynbuf) < fld->Length)
memcpy (dbf->BufDbf + fld->Offset + 1, dynbuf,
strlen (dynbuf));
else
memcpy (dbf->BufDbf + fld->Offset + 1, dynbuf,
fld->Length);
free (dynbuf);
}
}
break;
case 'N':
memset (dbf->BufDbf + fld->Offset + 1, '\0', fld->Length);
if (fld->Value)
{
if (fld->Value->Type == GAIA_INT_VALUE)
{
sprintf (dummy, FRMT64, fld->Value->IntValue);
if (strlen (dummy) <= fld->Length)
memcpy (dbf->BufDbf + fld->Offset + 1,
dummy, strlen (dummy));
}
if (fld->Value->Type == GAIA_DOUBLE_VALUE)
{
sprintf (fmt, "%%1.%df", fld->Decimals);
sprintf (dummy, fmt, fld->Value->DblValue);
if (strlen (dummy) <= fld->Length)
memcpy (dbf->BufDbf + fld->Offset + 1,
dummy, strlen (dummy));
}
}
break;
};
fld = fld->Next;
}
/* inserting entity in DBF file */
fwrite (dbf->BufDbf, 1, dbf->DbfReclen, dbf->flDbf);
(dbf->DbfRecno)++;
return 1;
conversion_error:
if (dbf->LastError)
free (dbf->LastError);
sprintf (dummy, "Invalid character sequence");
len = strlen (dummy);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, dummy);
return 0;
}
GAIAGEO_DECLARE void
gaiaFlushDbfHeader (gaiaDbfPtr dbf)
{
/* updates the DBF file header */
FILE *fl_dbf = dbf->flDbf;
int dbf_size = dbf->DbfSize;
int dbf_reclen = dbf->DbfReclen;
int dbf_recno = dbf->DbfRecno;
int endian_arch = dbf->endian_arch;
unsigned char bf[64];
/* writing the DBF file header */
*bf = 0x1a; /* DBF - this is theEOF marker */
fwrite (bf, 1, 1, fl_dbf);
gaia_fseek (fl_dbf, 0, SEEK_SET); /* repositioning at DBF file start */
memset (bf, '\0', 32);
*bf = 0x03; /* DBF magic number */
*(bf + 1) = 1; /* this is supposed to be the last update date [Year, Month, Day], but we ignore it at all */
*(bf + 2) = 1;
*(bf + 3) = 1;
gaiaExport32 (bf + 4, dbf_recno, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # records in this DBF */
gaiaExport16 (bf + 8, (short) dbf_size, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the file header size */
gaiaExport16 (bf + 10, (short) dbf_reclen, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the record length */
fwrite (bf, 1, 32, fl_dbf);
}
GAIAGEO_DECLARE int
gaiaReadDbfEntity (gaiaDbfPtr dbf, int current_row, int *deleted)
{
return gaiaReadDbfEntity_ex (dbf, current_row, deleted, 0);
}
GAIAGEO_DECLARE int
gaiaReadDbfEntity_ex (gaiaDbfPtr dbf, int current_row, int *deleted,
int text_dates)
{
/* trying to read an entity from DBF */
int rd;
int skpos;
gaia_off_t offset;
int len;
char errMsg[1024];
gaiaDbfFieldPtr pFld;
/* positioning and reading the DBF file */
offset =
dbf->DbfHdsz +
((gaia_off_t) current_row * (gaia_off_t) (dbf->DbfReclen));
if (dbf->memDbf != NULL)
skpos = gaiaMemFseek (dbf->memDbf, offset);
else
skpos = gaia_fseek (dbf->flDbf, offset, SEEK_SET);
if (skpos != 0)
goto eof;
if (dbf->memDbf != NULL)
rd = gaiaMemRead (dbf->BufDbf, dbf->DbfReclen, dbf->memDbf);
else
rd = fread (dbf->BufDbf, sizeof (unsigned char), dbf->DbfReclen,
dbf->flDbf);
if (rd != dbf->DbfReclen)
goto eof;
/* setting up the current DBF ENTITY */
gaiaResetDbfEntity (dbf->Dbf);
dbf->Dbf->RowId = current_row;
if (*(dbf->BufDbf) == '*')
{
/* deleted row */
*deleted = 1;
if (dbf->LastError)
free (dbf->LastError);
dbf->LastError = NULL;
return 1;
}
/* fetching the DBF values */
pFld = dbf->Dbf->First;
while (pFld)
{
if (!parseDbfField (dbf->BufDbf, dbf->IconvObj, pFld, text_dates))
{
char *text = malloc (pFld->Length + 1);
memcpy (text, dbf->BufDbf + pFld->Offset + 1, pFld->Length);
text[pFld->Length] = '\0';
spatialite_e
("**** libiconv: unable to convert string=\"%s\"\n", text);
free (text);
goto conversion_error;
}
pFld = pFld->Next;
}
if (dbf->LastError)
free (dbf->LastError);
dbf->LastError = NULL;
*deleted = 0;
return 1;
eof:
if (dbf->LastError)
free (dbf->LastError);
dbf->LastError = NULL;
return 0;
conversion_error:
if (dbf->LastError)
free (dbf->LastError);
sprintf (errMsg, "Invalid character sequence");
sprintf (errMsg, "Invalid character sequence at DBF line %d", current_row);
len = strlen (errMsg);
dbf->LastError = malloc (len + 1);
strcpy (dbf->LastError, errMsg);
return 0;
}
#endif /* ICONV enabled/disabled */
#ifdef _WIN32
GAIAGEO_DECLARE FILE *
gaia_win_fopen (const char *path, const char *mode)
{
/* only for Windows: opening a file with an UTF16 path */
wchar_t *path16;
wchar_t *mode16;
int len;
FILE *fl;
/* converting the PATH from UTF-8 to UNICODE UTF-16 */
len = MultiByteToWideChar (CP_UTF8, 0, path, -1, NULL, 0);
path16 = malloc ((len + 1) * 2);
len = MultiByteToWideChar (CP_UTF8, 0, path, -1, path16, len);
/* converting the MODE from UTF-8 to UNICODE UTF-16 */
len = MultiByteToWideChar (CP_UTF8, 0, mode, -1, NULL, 0);
mode16 = malloc ((len + 1) * 2);
MultiByteToWideChar (CP_UTF8, 0, mode, -1, mode16, len);
/* calling the UTF-16 version of fopen() */
fl = _wfopen (path16, mode16);
/* memory cleanup */
free (path16);
free (mode16);
return fl;
}
#endif
libspatialite-5.1.0/src/gaiageo/gg_transform.c 0000644 0001750 0001750 00000210273 14463127014 016312 0000000 0000000 /*
gg_transform.c -- Gaia PROJ.4 wrapping
version 5.1-0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32)
#include
#include
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#include
#include
#ifndef OMIT_PROJ /* including PROJ.4 */
#ifdef PROJ_NEW /* supporting PROJ.6 */
#include
#else /* supporting old PROJ.4 */
#include
#endif
#ifndef OMIT_PROJ /* including PROJ.4 */
#ifndef PROJ_NEW /* supporting old PROJ.4 */
static int
gaiaIsLongLat (const char *str)
{
/* checks if we have to do with ANGLES if +proj=longlat is defined */
if (str == NULL)
return 0;
if (strstr (str, "+proj=longlat") != NULL)
return 1;
return 0;
}
#endif
#ifdef PROJ_NEW /* only if PROJ.6 is supported */
GAIAGEO_DECLARE void
gaiaResetProjErrorMsg_r (const void *p_cache)
{
/* resets the PROJ error message */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache != NULL)
{
if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
&& cache->magic2 == SPATIALITE_CACHE_MAGIC2)
{
if (cache->gaia_proj_error_msg != NULL)
sqlite3_free (cache->gaia_proj_error_msg);
cache->gaia_proj_error_msg = NULL;
}
}
}
GAIAGEO_DECLARE const char *
gaiaSetProjDatabasePath (const void *p_cache, const char *path)
{
/* return the currently set PATH leading to the private PROJ.6 database */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache != NULL)
{
if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
&& cache->magic2 == SPATIALITE_CACHE_MAGIC2)
{
if (!proj_context_set_database_path
(cache->PROJ_handle, path, NULL, NULL))
return NULL;
return proj_context_get_database_path (cache->PROJ_handle);
}
}
return NULL;
}
GAIAGEO_DECLARE const char *
gaiaGetProjDatabasePath (const void *p_cache)
{
/* return the currently set PATH leading to the private PROJ.6 database */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache != NULL)
{
if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
&& cache->magic2 == SPATIALITE_CACHE_MAGIC2)
return proj_context_get_database_path (cache->PROJ_handle);
}
return NULL;
}
GAIAGEO_DECLARE const char *
gaiaGetProjErrorMsg_r (const void *p_cache)
{
/* return the latest PROJ error message */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache != NULL)
{
if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
&& cache->magic2 == SPATIALITE_CACHE_MAGIC2)
{
if (cache->gaia_proj_error_msg != NULL)
return cache->gaia_proj_error_msg;
}
}
return NULL;
}
GAIAGEO_DECLARE void
gaiaSetProjErrorMsg_r (const void *p_cache, const char *msg)
{
/* setting the latest PROJ error message */
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
if (cache != NULL)
{
if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
&& cache->magic2 == SPATIALITE_CACHE_MAGIC2)
{
if (cache->gaia_proj_error_msg != NULL)
sqlite3_free (cache->gaia_proj_error_msg);
cache->gaia_proj_error_msg = sqlite3_mprintf ("%s", msg);
}
}
}
#endif
GAIAGEO_DECLARE double
gaiaRadsToDegs (double rads)
{
/* converts an ANGLE from radians to degrees */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
return proj_todeg (rads);
#else /* supporting old PROJ.4 */
return rads * RAD_TO_DEG;
#endif
}
GAIAGEO_DECLARE double
gaiaDegsToRads (double degs)
{
/* converts an ANGLE from degrees to radians */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
return proj_torad (degs);
#else /* supporting old PROJ.4 */
return degs * DEG_TO_RAD;
#endif
}
static int
do_transfom_proj (gaiaGeomCollPtr org, gaiaGeomCollPtr dst, int ignore_z,
int ignore_m, int from_radians, int to_radians, void *xfrom,
void *xto, void *x_from_to)
{
/* supporting either old PROJ.4 or new PROJ.6 */
int error = 0;
int ret;
#ifdef PROJ_NEW /* supporting new PROJ.6 */
int result_count;
#endif
int ib;
int cnt;
int i;
double *xx;
double *yy;
double *zz;
double *old_zz = NULL;
double *mm = NULL;
double *old_mm = NULL;
double x;
double y;
double z;
double m;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaLinestringPtr dst_ln;
gaiaPolygonPtr pg;
gaiaPolygonPtr dst_pg;
gaiaRingPtr rng;
gaiaRingPtr dst_rng;
#ifdef PROJ_NEW /* only if new PROJ.6 is supported */
PJ *from_to_cs = (PJ *) x_from_to;
if (xfrom == NULL)
xfrom = NULL; /* silencing stupid compiler warnings - unused arg */
if (xto == NULL)
xto = NULL; /* silencing stupid compiler warnings - unused arg */
#else /* only id old PROJ.4 is supported */
projPJ from_cs = (projPJ) xfrom;
projPJ to_cs = (projPJ) xto;
if (x_from_to == NULL)
x_from_to = NULL; /* silencing stupid compiler warnings - unused arg */
#endif
cnt = 0;
pt = org->FirstPoint;
while (pt)
{
/* counting POINTs */
cnt++;
pt = pt->Next;
}
if (cnt)
{
/* reprojecting POINTs */
xx = malloc (sizeof (double) * cnt);
yy = malloc (sizeof (double) * cnt);
zz = malloc (sizeof (double) * cnt);
mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* zeroing unused coordinates */
if (ignore_z || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_M)
zz[i] = 0.0;
if (ignore_m || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_Z)
mm[i] = 0.0;
}
if (ignore_z
&& (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M))
old_zz = malloc (sizeof (double) * cnt);
if (ignore_m
&& (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M))
old_mm = malloc (sizeof (double) * cnt);
i = 0;
pt = org->FirstPoint;
while (pt)
{
/* inserting points to be converted in temporary arrays */
if (from_radians)
{
xx[i] = gaiaDegsToRads (pt->X);
yy[i] = gaiaDegsToRads (pt->Y);
}
else
{
xx[i] = pt->X;
yy[i] = pt->Y;
}
if (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
old_zz[i] = pt->Z;
else
zz[i] = pt->Z;
}
if (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
old_mm[i] = pt->M;
else
mm[i] = pt->M;
}
i++;
pt = pt->Next;
}
/* applying reprojection */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
result_count =
proj_trans_generic (from_to_cs, PJ_FWD, xx, sizeof (double), cnt,
yy, sizeof (double), cnt, zz, sizeof (double),
cnt, mm, sizeof (double), cnt);
if (result_count == cnt)
ret = 0;
else
ret = 1;
#else /* supporting old PROJ.4 */
ret = pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz);
#endif
if (ret == 0)
{
/* inserting the reprojected POINTs in the new GEOMETRY */
for (i = 0; i < cnt; i++)
{
if (to_radians)
{
x = gaiaRadsToDegs (xx[i]);
y = gaiaRadsToDegs (yy[i]);
}
else
{
x = xx[i];
y = yy[i];
}
if (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
z = old_zz[i];
else
z = zz[i];
}
if (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
m = old_mm[i];
else
m = mm[i];
}
if (dst->DimensionModel == GAIA_XY_Z)
gaiaAddPointToGeomCollXYZ (dst, x, y, z);
else if (dst->DimensionModel == GAIA_XY_M)
gaiaAddPointToGeomCollXYM (dst, x, y, m);
else if (dst->DimensionModel == GAIA_XY_Z_M)
gaiaAddPointToGeomCollXYZM (dst, x, y, z, m);
else
gaiaAddPointToGeomColl (dst, x, y);
}
}
else
error = 1;
free (xx);
free (yy);
free (zz);
free (mm);
if (old_zz != NULL)
free (old_zz);
if (old_mm != NULL)
free (old_mm);
xx = NULL;
yy = NULL;
zz = NULL;
mm = NULL;
old_zz = NULL;
old_mm = NULL;
}
if (error)
goto stop;
ln = org->FirstLinestring;
while (ln)
{
/* reprojecting LINESTRINGs */
cnt = ln->Points;
xx = malloc (sizeof (double) * cnt);
yy = malloc (sizeof (double) * cnt);
zz = malloc (sizeof (double) * cnt);
mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* zeroing unused coordinates */
if (ignore_z || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_M)
zz[i] = 0.0;
if (ignore_m || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_Z)
mm[i] = 0.0;
}
if (ignore_z
&& (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M))
old_zz = malloc (sizeof (double) * cnt);
if (ignore_m
&& (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M))
old_mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* inserting points to be converted in temporary arrays */
z = 0.0;
m = 0.0;
if (ln->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (ln->Coords, i, &x, &y, &z);
}
else if (ln->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (ln->Coords, i, &x, &y, &m);
}
else if (ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (ln->Coords, i, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ln->Coords, i, &x, &y);
}
if (from_radians)
{
xx[i] = gaiaDegsToRads (x);
yy[i] = gaiaDegsToRads (y);
}
else
{
xx[i] = x;
yy[i] = y;
}
if (ln->DimensionModel == GAIA_XY_Z
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
old_zz[i] = z;
else
zz[i] = z;
}
if (ln->DimensionModel == GAIA_XY_M
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
old_mm[i] = m;
else
mm[i] = m;
}
}
/* applying reprojection */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
result_count =
proj_trans_generic (from_to_cs, PJ_FWD, xx, sizeof (double), cnt,
yy, sizeof (double), cnt, zz, sizeof (double),
cnt, mm, sizeof (double), cnt);
if (result_count == cnt)
ret = 0;
else
ret = 1;
#else /* supporting old PROJ.4 */
ret = pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz);
#endif
if (ret == 0)
{
/* inserting the reprojected LINESTRING in the new GEOMETRY */
dst_ln = gaiaAddLinestringToGeomColl (dst, cnt);
for (i = 0; i < cnt; i++)
{
/* setting LINESTRING points */
if (to_radians)
{
x = gaiaRadsToDegs (xx[i]);
y = gaiaRadsToDegs (yy[i]);
}
else
{
x = xx[i];
y = yy[i];
}
if (ln->DimensionModel == GAIA_XY_Z
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
z = old_zz[i];
else
z = zz[i];
}
if (ln->DimensionModel == GAIA_XY_M
|| ln->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
m = old_mm[i];
else
m = mm[i];
}
if (dst_ln->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst_ln->Coords, i, x, y, z);
}
else if (dst_ln->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst_ln->Coords, i, x, y, m);
}
else if (dst_ln->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst_ln->Coords, i, x, y, z, m);
}
else
{
gaiaSetPoint (dst_ln->Coords, i, x, y);
}
}
}
else
error = 1;
free (xx);
free (yy);
free (zz);
free (mm);
if (old_zz != NULL)
free (old_zz);
if (old_mm != NULL)
free (old_mm);
xx = NULL;
yy = NULL;
zz = NULL;
mm = NULL;
old_zz = NULL;
old_mm = NULL;
if (error)
goto stop;
ln = ln->Next;
}
pg = org->FirstPolygon;
while (pg)
{
/* reprojecting POLYGONs */
rng = pg->Exterior;
cnt = rng->Points;
dst_pg = gaiaAddPolygonToGeomColl (dst, cnt, pg->NumInteriors);
xx = malloc (sizeof (double) * cnt);
yy = malloc (sizeof (double) * cnt);
zz = malloc (sizeof (double) * cnt);
mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* zeroing unused coordinates */
if (ignore_z || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_M)
zz[i] = 0.0;
if (ignore_m || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_Z)
mm[i] = 0.0;
}
if (ignore_z
&& (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M))
old_zz = malloc (sizeof (double) * cnt);
if (ignore_m
&& (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M))
old_mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* inserting points to be converted in temporary arrays [EXTERIOR RING] */
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, i, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, i, &x, &y);
}
if (from_radians)
{
xx[i] = gaiaDegsToRads (x);
yy[i] = gaiaDegsToRads (y);
}
else
{
xx[i] = x;
yy[i] = y;
}
if (rng->DimensionModel == GAIA_XY_Z
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
old_zz[i] = z;
else
zz[i] = z;
}
if (rng->DimensionModel == GAIA_XY_M
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
old_mm[i] = m;
else
mm[i] = m;
}
}
/* applying reprojection */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
result_count =
proj_trans_generic (from_to_cs, PJ_FWD, xx, sizeof (double), cnt,
yy, sizeof (double), cnt, zz, sizeof (double),
cnt, mm, sizeof (double), cnt);
if (result_count == cnt)
ret = 0;
else
ret = 1;
#else /* supporting old PROJ.4 */
ret = pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz);
#endif
if (ret == 0)
{
/* inserting the reprojected POLYGON in the new GEOMETRY */
dst_rng = dst_pg->Exterior;
for (i = 0; i < cnt; i++)
{
/* setting EXTERIOR RING points */
if (to_radians)
{
x = gaiaRadsToDegs (xx[i]);
y = gaiaRadsToDegs (yy[i]);
}
else
{
x = xx[i];
y = yy[i];
}
if (rng->DimensionModel == GAIA_XY_Z
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
z = old_zz[i];
else
z = zz[i];
}
if (rng->DimensionModel == GAIA_XY_M
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
m = old_mm[i];
else
m = mm[i];
}
if (dst_rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z);
}
else if (dst_rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst_rng->Coords, i, x, y, m);
}
else if (dst_rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m);
}
else
{
gaiaSetPoint (dst_rng->Coords, i, x, y);
}
}
}
else
error = 1;
free (xx);
free (yy);
free (zz);
free (mm);
if (old_zz != NULL)
free (old_zz);
if (old_mm != NULL)
free (old_mm);
xx = NULL;
yy = NULL;
zz = NULL;
mm = NULL;
old_zz = NULL;
old_mm = NULL;
if (error)
goto stop;
for (ib = 0; ib < pg->NumInteriors; ib++)
{
/* processing INTERIOR RINGS */
rng = pg->Interiors + ib;
cnt = rng->Points;
xx = malloc (sizeof (double) * cnt);
yy = malloc (sizeof (double) * cnt);
zz = malloc (sizeof (double) * cnt);
mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* zeroing unused coordinates */
if (ignore_z || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_M)
zz[i] = 0.0;
if (ignore_m || org->DimensionModel == GAIA_XY
|| org->DimensionModel == GAIA_XY_Z)
mm[i] = 0.0;
}
if (ignore_z
&& (org->DimensionModel == GAIA_XY_Z
|| org->DimensionModel == GAIA_XY_Z_M))
old_zz = malloc (sizeof (double) * cnt);
if (ignore_m
&& (org->DimensionModel == GAIA_XY_M
|| org->DimensionModel == GAIA_XY_Z_M))
old_mm = malloc (sizeof (double) * cnt);
for (i = 0; i < cnt; i++)
{
/* inserting points to be converted in temporary arrays [INTERIOR RING] */
z = 0.0;
m = 0.0;
if (rng->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z);
}
else if (rng->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, i, &x, &y, &m);
}
else if (rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, i, &x, &y);
}
if (from_radians)
{
xx[i] = gaiaDegsToRads (x);
yy[i] = gaiaDegsToRads (y);
}
else
{
xx[i] = x;
yy[i] = y;
}
if (rng->DimensionModel == GAIA_XY_Z
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
old_zz[i] = z;
else
zz[i] = z;
}
if (rng->DimensionModel == GAIA_XY_M
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
old_mm[i] = m;
else
mm[i] = m;
}
}
/* applying reprojection */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
result_count =
proj_trans_generic (from_to_cs, PJ_FWD, xx, sizeof (double),
cnt, yy, sizeof (double), cnt, zz,
sizeof (double), cnt, mm,
sizeof (double), cnt);
if (result_count == cnt)
ret = 0;
else
ret = 1;
#else /* supporting old PROJ.4 */
ret = pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz);
#endif
if (ret == 0)
{
/* inserting the reprojected POLYGON in the new GEOMETRY */
dst_rng = gaiaAddInteriorRing (dst_pg, ib, cnt);
for (i = 0; i < cnt; i++)
{
/* setting INTERIOR RING points */
if (to_radians)
{
x = gaiaRadsToDegs (xx[i]);
y = gaiaRadsToDegs (yy[i]);
}
else
{
x = xx[i];
y = yy[i];
}
if (rng->DimensionModel == GAIA_XY_Z
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_z)
z = old_zz[i];
else
z = zz[i];
}
if (rng->DimensionModel == GAIA_XY_M
|| rng->DimensionModel == GAIA_XY_Z_M)
{
if (ignore_m)
m = old_mm[i];
else
m = mm[i];
}
if (dst_rng->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z);
}
else if (dst_rng->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (dst_rng->Coords, i, x, y, m);
}
else if (dst_rng->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z,
m);
}
else
{
gaiaSetPoint (dst_rng->Coords, i, x, y);
}
}
}
else
error = 1;
free (xx);
free (yy);
free (zz);
free (mm);
if (old_zz != NULL)
free (old_zz);
if (old_mm != NULL)
free (old_mm);
xx = NULL;
yy = NULL;
zz = NULL;
mm = NULL;
old_zz = NULL;
old_mm = NULL;
if (error)
goto stop;
}
pg = pg->Next;
}
stop:
#endif
return error;
}
static gaiaGeomCollPtr
gaiaTransformCommon (void *x_handle, const void *p_cache, gaiaGeomCollPtr org,
const char *proj_string_1,
const char *proj_string_2, gaiaProjAreaPtr proj_bbox,
int ignore_z, int ignore_m)
{
/* creates a new GEOMETRY reprojecting coordinates from the original one */
int error = 0;
#ifdef PROJ_NEW /* supporting new PROJ.6 */
PJ_CONTEXT *handle = (PJ_CONTEXT *) x_handle;
PJ *from_to_pre;
PJ *from_to_cs;
int proj_is_cached = 0;
#else /* supporting old PROJ.4 */
if (p_cache == NULL)
p_cache = NULL; /* silencing stupid compiler warnings about unused args */
projCtx handle = (projCtx) x_handle;
projPJ from_cs;
projPJ to_cs;
#endif
int from_radians;
int to_radians;
gaiaGeomCollPtr dst;
/* preliminary validity check */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
gaiaResetProjErrorMsg_r (p_cache);
#endif
if (proj_bbox == NULL)
proj_bbox = NULL; /* silencing stupid compiler warnings about unused args */
if (proj_string_1 == NULL)
return NULL;
#ifdef PROJ_NEW /* supporting new PROJ.6 */
if (gaiaCurrentCachedProjMatches
(p_cache, proj_string_1, proj_string_2, proj_bbox))
{
from_to_cs = gaiaGetCurrentCachedProj (p_cache);
if (from_to_cs != NULL)
{
proj_is_cached = 1;
goto skip_cached;
}
}
if (proj_string_2 != NULL)
{
PJ_AREA *area = NULL;
if (proj_bbox != NULL)
{
area = proj_area_create ();
proj_area_set_bbox (area, proj_bbox->WestLongitude,
proj_bbox->SouthLatitude,
proj_bbox->EastLongitude,
proj_bbox->NorthLatitude);
}
from_to_pre =
proj_create_crs_to_crs (handle, proj_string_1, proj_string_2,
area);
if (!from_to_pre)
return NULL;
from_to_cs = proj_normalize_for_visualization (handle, from_to_pre);
proj_destroy (from_to_pre);
if (area != NULL)
proj_area_destroy (area);
if (!from_to_cs)
return NULL;
proj_is_cached =
gaiaSetCurrentCachedProj (p_cache, from_to_cs, proj_string_1,
proj_string_2, proj_bbox);
}
else /* PROJ_STRING - PIPELINE */
{
from_to_cs = proj_create (handle, proj_string_1);
if (!from_to_cs)
return NULL;
proj_is_cached =
gaiaSetCurrentCachedProj (p_cache, from_to_cs, proj_string_1,
NULL, NULL);
}
skip_cached:
#else /* supporting old PROJ.4 */
if (proj_string_2 == NULL)
return NULL;
if (handle != NULL)
{
from_cs = pj_init_plus_ctx (handle, proj_string_1);
to_cs = pj_init_plus_ctx (handle, proj_string_2);
}
else
{
from_cs = pj_init_plus (proj_string_1);
to_cs = pj_init_plus (proj_string_2);
}
if (!from_cs)
{
if (to_cs)
pj_free (to_cs);
return NULL;
}
if (!to_cs)
{
pj_free (from_cs);
return NULL;
}
#endif
if (org->DimensionModel == GAIA_XY_Z)
dst = gaiaAllocGeomCollXYZ ();
else if (org->DimensionModel == GAIA_XY_M)
dst = gaiaAllocGeomCollXYM ();
else if (org->DimensionModel == GAIA_XY_Z_M)
dst = gaiaAllocGeomCollXYZM ();
else
dst = gaiaAllocGeomColl ();
#ifdef PROJ_NEW /* supporting new PROJ.6 */
from_radians = proj_angular_input (from_to_cs, PJ_FWD);
to_radians = proj_angular_output (from_to_cs, PJ_FWD);
error =
do_transfom_proj (org, dst, ignore_z, ignore_m, from_radians,
to_radians, NULL, NULL, from_to_cs);
#else /* supporting old PROJ.4 */
from_radians = gaiaIsLongLat (proj_string_1);
to_radians = gaiaIsLongLat (proj_string_2);
error =
do_transfom_proj (org, dst, ignore_z, ignore_m, from_radians,
to_radians, from_cs, to_cs, NULL);
#endif
/* destroying the PROJ4 params */
#ifdef PROJ_NEW /* supporting new PROJ.6 */
if (!proj_is_cached)
proj_destroy (from_to_cs);
#else /* supporting old PROJ.4 */
pj_free (from_cs);
pj_free (to_cs);
#endif
if (error)
{
/* some error occurred */
gaiaPointPtr pP;
gaiaPointPtr pPn;
gaiaLinestringPtr pL;
gaiaLinestringPtr pLn;
gaiaPolygonPtr pA;
gaiaPolygonPtr pAn;
pP = dst->FirstPoint;
while (pP != NULL)
{
pPn = pP->Next;
gaiaFreePoint (pP);
pP = pPn;
}
pL = dst->FirstLinestring;
while (pL != NULL)
{
pLn = pL->Next;
gaiaFreeLinestring (pL);
pL = pLn;
}
pA = dst->FirstPolygon;
while (pA != NULL)
{
pAn = pA->Next;
gaiaFreePolygon (pA);
pA = pAn;
}
dst->FirstPoint = NULL;
dst->LastPoint = NULL;
dst->FirstLinestring = NULL;
dst->LastLinestring = NULL;
dst->FirstPolygon = NULL;
dst->LastPolygon = NULL;
}
if (dst)
{
gaiaMbrGeometry (dst);
dst->DeclaredType = org->DeclaredType;
}
return dst;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransform (gaiaGeomCollPtr org, const char *proj_from, const char *proj_to)
{
return gaiaTransformEx (org, proj_from, proj_to, NULL);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransform_r (const void *p_cache, gaiaGeomCollPtr org,
const char *proj_from, const char *proj_to)
{
return gaiaTransformEx_r (p_cache, org, proj_from, proj_to, NULL);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformEx (gaiaGeomCollPtr org, const char *proj_string_1,
const char *proj_string_2, gaiaProjAreaPtr proj_bbox)
{
return gaiaTransformCommon (NULL, NULL, org, proj_string_1, proj_string_2,
proj_bbox, 0, 0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformEx_r (const void *p_cache, gaiaGeomCollPtr org,
const char *proj_string_1, const char *proj_string_2,
gaiaProjAreaPtr proj_bbox)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
void *handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->PROJ_handle;
if (handle == NULL)
return NULL;
return gaiaTransformCommon (handle, cache, org, proj_string_1,
proj_string_2, proj_bbox, 0, 0);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformXY (gaiaGeomCollPtr org, const char *proj_from,
const char *proj_to)
{
return gaiaTransformCommon (NULL, NULL, org,
proj_from, proj_to, NULL, 1, 1);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformXY_r (const void *p_cache, gaiaGeomCollPtr org,
const char *proj_from, const char *proj_to)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
void *handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->PROJ_handle;
if (handle == NULL)
return NULL;
return gaiaTransformCommon (handle, cache, org,
proj_from, proj_to, NULL, 1, 1);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformXYZ (gaiaGeomCollPtr org, const char *proj_from,
const char *proj_to)
{
return gaiaTransformCommon (NULL, NULL, org,
proj_from, proj_to, NULL, 0, 1);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTransformXYZ_r (const void *p_cache, gaiaGeomCollPtr org,
const char *proj_from, const char *proj_to)
{
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
void *handle = NULL;
if (cache == NULL)
return NULL;
if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
|| cache->magic2 != SPATIALITE_CACHE_MAGIC2)
return NULL;
handle = cache->PROJ_handle;
if (handle == NULL)
return NULL;
return gaiaTransformCommon (handle, cache, org,
proj_from, proj_to, NULL, 0, 1);
}
#ifdef PROJ_NEW /* only if new PROJ.6 is supported */
GAIAGEO_DECLARE char *
gaiaGetProjString (const void *p_cache, const char *auth_name, int auth_srid)
{
/* return the proj-string expression corresponding to some CRS */
PJ *crs_def;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
const char *proj_string;
int len;
char *result;
char xsrid[64];
sprintf (xsrid, "%d", auth_srid);
crs_def =
proj_create_from_database (cache->PROJ_handle, auth_name, xsrid,
PJ_CATEGORY_CRS, 0, NULL);
if (crs_def == NULL)
return NULL;
proj_string =
proj_as_proj_string (cache->PROJ_handle, crs_def, PJ_PROJ_5, NULL);
if (proj_string == NULL)
{
proj_destroy (crs_def);
return NULL;
}
len = strlen (proj_string);
result = malloc (len + 1);
strcpy (result, proj_string);
proj_destroy (crs_def);
return result;
}
GAIAGEO_DECLARE char *
gaiaGetProjWKT (const void *p_cache, const char *auth_name, int auth_srid,
int style, int indented, int indentation)
{
/* return the WKT expression corresponding to some CRS */
PJ *crs_def;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
int proj_style;
const char *wkt;
int len;
char *result;
char xsrid[64];
char dummy[64];
char *options[4];
options[1] = dummy;
options[2] = "OUTPUT_AXIS=AUTO";
options[3] = NULL;
sprintf (xsrid, "%d", auth_srid);
crs_def =
proj_create_from_database (cache->PROJ_handle, auth_name, xsrid,
PJ_CATEGORY_CRS, 0, NULL);
if (crs_def == NULL)
return NULL;
switch (style)
{
case GAIA_PROJ_WKT_GDAL:
proj_style = PJ_WKT1_GDAL;
break;
case GAIA_PROJ_WKT_ESRI:
proj_style = PJ_WKT1_ESRI;
break;
case GAIA_PROJ_WKT_ISO_2015:
proj_style = PJ_WKT2_2015;
break;
default:
proj_style = PJ_WKT2_2015;
break;
};
if (indented)
options[0] = "MULTILINE=YES";
else
options[0] = "MULTILINE=NO";
if (indentation < 1)
indentation = 1;
if (indentation > 8)
indentation = 8;
sprintf (dummy, "INDENTATION_WIDTH=%d", indentation);
wkt =
proj_as_wkt (cache->PROJ_handle, crs_def, proj_style,
(const char *const *) options);
if (wkt == NULL)
{
proj_destroy (crs_def);
return NULL;
}
len = strlen (wkt);
result = malloc (len + 1);
strcpy (result, wkt);
proj_destroy (crs_def);
return result;
}
GAIAGEO_DECLARE int
gaiaGuessSridFromWKT (sqlite3 * sqlite, const void *p_cache, const char *wkt,
int *srid)
{
/* return the SRID value corresponding to a given WKT expression */
PJ *crs1 = NULL;
PJ *crs2 = NULL;
struct splite_internal_cache *cache =
(struct splite_internal_cache *) p_cache;
sqlite3_stmt *stmt = NULL;
int ret;
const char *sql;
int xsrid = -1;
/* sanity check */
if (cache == NULL)
goto error;
if (cache->PROJ_handle == NULL)
goto error;
/* attempting to parse the WKT expression */
crs1 = proj_create_from_wkt (cache->PROJ_handle, wkt, NULL, NULL, NULL);
if (crs1 == NULL)
{
spatialite_e
("gaiaGuessSridFromWKT: invalid/malformed WKT expression\n");
goto error;
}
sql = "SELECT srid, Upper(auth_name), auth_srid FROM spatial_ref_sys";
ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
if (ret != SQLITE_OK)
{
spatialite_e ("gaiaGuessSridFromWKT: %s\n", sqlite3_errmsg (sqlite));
goto error;
}
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
char dummy[64];
int srid = sqlite3_column_int (stmt, 0);
const char *auth_name =
(const char *) sqlite3_column_text (stmt, 1);
int auth_srid = sqlite3_column_int (stmt, 2);
sprintf (dummy, "%d", auth_srid);
/* parsing some CRS */
crs2 =
proj_create_from_database (cache->PROJ_handle, auth_name,
dummy, PJ_CATEGORY_CRS, 0, NULL);
if (crs2 != NULL)
{
/* ok, it's a valid CRS - comparing */
if (proj_is_equivalent_to
(crs1, crs2,
PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS))
{
xsrid = srid;
proj_destroy (crs2);
break;
}
proj_destroy (crs2);
}
}
}
sqlite3_finalize (stmt);
proj_destroy (crs1);
*srid = xsrid;
gaiaResetProjErrorMsg_r (cache);
return 1;
error:
if (stmt != NULL)
sqlite3_finalize (stmt);
if (crs1 != NULL)
proj_destroy (crs1);
*srid = xsrid;
return 0;
}
#endif
#endif /* end including PROJ.4 */
GAIAGEO_DECLARE void
gaiaShiftLongitude (gaiaGeomCollPtr geom)
{
/* returns a geometry that is the old geometry with negative longitudes shift by 360 */
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* shifting POINTs */
if (point->X < 0)
{
point->X += 360.0;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* shifting LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
if (x < 0)
{
x += 360.0;
}
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* shifting POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* shifting the 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);
}
if (x < 0)
{
x += 360.0;
}
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* shifting the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
if (x < 0)
{
x += 360.0;
}
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeCircle (double cx, double cy, double radius, double step)
{
/* return a Linestring approximating a Circle */
return gaiaMakeEllipse (cx, cy, radius, radius, step);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeArc (double cx,
double cy, double radius, double start, double stop, double step)
{
/* return a Linestring approximating a Circular Arc */
return gaiaMakeEllipticArc (cx, cy, radius, radius, start, stop, step);
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeEllipse (double cx, double cy, double x_axis, double y_axis,
double step)
{
/* return a Linestring approximating an Ellipse */
gaiaDynamicLinePtr dyn;
double x;
double y;
double angle = 0.0;
int points = 0;
gaiaPointPtr pt;
gaiaGeomCollPtr geom;
gaiaLinestringPtr ln;
int iv = 0;
if (step < 0.0)
step *= -1.0;
if (step == 0.0)
step = 10.0;
if (step < 0.1)
step = 0.1;
if (step > 45.0)
step = 45.0;
if (x_axis < 0.0)
x_axis *= -1.0;
if (y_axis < 0.0)
y_axis *= -1.0;
dyn = gaiaAllocDynamicLine ();
while (angle < 360.0)
{
double rads = angle * .0174532925199432958;
x = cx + (x_axis * cos (rads));
y = cy + (y_axis * sin (rads));
gaiaAppendPointToDynamicLine (dyn, x, y);
angle += step;
}
/* closing the ellipse */
gaiaAppendPointToDynamicLine (dyn, dyn->First->X, dyn->First->Y);
pt = dyn->First;
while (pt)
{
/* counting how many points */
points++;
pt = pt->Next;
}
if (points == 0)
{
gaiaFreeDynamicLine (dyn);
return NULL;
}
geom = gaiaAllocGeomColl ();
ln = gaiaAddLinestringToGeomColl (geom, points);
pt = dyn->First;
while (pt)
{
/* setting Vertices */
gaiaSetPoint (ln->Coords, iv, pt->X, pt->Y);
iv++;
pt = pt->Next;
}
gaiaFreeDynamicLine (dyn);
return geom;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeEllipticArc (double cx,
double cy, double x_axis, double y_axis, double start,
double stop, double step)
{
/* return a Linestring approximating an Elliptic Arc */
gaiaDynamicLinePtr dyn;
double x;
double y;
double angle;
double rads;
int points = 0;
gaiaPointPtr pt;
gaiaGeomCollPtr geom;
gaiaLinestringPtr ln;
int iv = 0;
if (step < 0.0)
step *= -1.0;
if (step == 0.0)
step = 10.0;
if (step < 0.1)
step = 0.1;
if (step > 45.0)
step = 45.0;
if (x_axis < 0.0)
x_axis *= -1.0;
if (y_axis < 0.0)
y_axis *= -1.0;
/* normalizing Start/Stop angles */
while (start >= 360.0)
start -= 360.0;
while (start <= -720.0)
start += 360;
while (stop >= 360.0)
stop -= 360.0;
while (stop <= -720.0)
stop += 360;
if (start < 0.0)
start = 360.0 + start;
if (stop < 0.0)
stop = 360.0 + stop;
if (start > stop)
stop += 360.0;
dyn = gaiaAllocDynamicLine ();
angle = start;
while (angle < stop)
{
rads = angle * .0174532925199432958;
x = cx + (x_axis * cos (rads));
y = cy + (y_axis * sin (rads));
gaiaAppendPointToDynamicLine (dyn, x, y);
angle += step;
points++;
}
if (points == 0)
{
gaiaFreeDynamicLine (dyn);
return NULL;
}
/* closing the arc */
rads = stop * .0174532925199432958;
x = cx + (x_axis * cos (rads));
y = cy + (y_axis * sin (rads));
if (x != dyn->Last->X || y != dyn->Last->Y)
gaiaAppendPointToDynamicLine (dyn, x, y);
pt = dyn->First;
points = 0;
while (pt)
{
/* counting how many points */
points++;
pt = pt->Next;
}
if (points == 0)
{
gaiaFreeDynamicLine (dyn);
return NULL;
}
geom = gaiaAllocGeomColl ();
ln = gaiaAddLinestringToGeomColl (geom, points);
pt = dyn->First;
while (pt)
{
/* setting Vertices */
gaiaSetPoint (ln->Coords, iv, pt->X, pt->Y);
iv++;
pt = pt->Next;
}
gaiaFreeDynamicLine (dyn);
return geom;
}
GAIAGEO_DECLARE void
gaiaShiftCoords (gaiaGeomCollPtr geom, double shift_x, double shift_y)
{
/* returns a geometry that is the old geometry with required shifting applied to coordinates */
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* shifting POINTs */
point->X += shift_x;
point->Y += shift_y;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* shifting LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
x += shift_x;
y += shift_y;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* shifting POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* shifting the 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);
}
x += shift_x;
y += shift_y;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* shifting the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
x += shift_x;
y += shift_y;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE void
gaiaShiftCoords3D (gaiaGeomCollPtr geom, double shift_x, double shift_y,
double shift_z)
{
/* returns a geometry that is the old geometry with required shifting applied to coordinates */
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* shifting POINTs */
point->X += shift_x;
point->Y += shift_y;
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
point->Z += shift_z;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* shifting LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
x += shift_x;
y += shift_y;
z += shift_z;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* shifting POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* shifting the 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);
}
x += shift_x;
y += shift_y;
z += shift_z;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* shifting the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
x += shift_x;
y += shift_y;
z += shift_z;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
static void
normalizePoint (double *x, double *y)
{
if ((-180.0 <= *x) && (*x <= 180.0) && (-90.0 <= *y) && (*y <= 90.0))
{
/* then this point is already OK */
return;
}
if ((*x > 180.0) || (*x < -180.0))
{
int numCycles = (int) (*x / 360.0);
*x -= numCycles * 360.0;
}
if (*x > 180.0)
{
*x -= 360.0;
}
if (*x < -180.0)
{
*x += 360.0;
}
if ((*y > 90.0) || (*y < -90.0))
{
int numCycles = (int) (*y / 360.0);
*y -= numCycles * 360.0;
}
if (*y > 180.0)
{
*y = -1.0 * (*y - 180.0);
}
if (*y < -180.0)
{
*y = -1.0 * (*y + 180.0);
}
if (*y > 90.0)
{
*y = 180 - *y;
}
if (*y < -90.0)
{
*y = -180.0 - *y;
}
}
GAIAGEO_DECLARE void
gaiaNormalizeLonLat (gaiaGeomCollPtr geom)
{
/* returns a geometry that is the old geometry with all latitudes shifted
into the range -90 to 90, and all longitudes shifted into the range -180 to
180.
*/
int ib;
int iv;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
normalizePoint (&(point->X), &(point->Y));
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* shifting LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
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);
}
normalizePoint (&x, &y);
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* shifting POLYGONs */
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* shifting the 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);
}
normalizePoint (&x, &y);
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* shifting the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
normalizePoint (&x, &y);
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE void
gaiaScaleCoords (gaiaGeomCollPtr geom, double scale_x, double scale_y)
{
/* returns a geometry that is the old geometry with required scaling applied to coordinates */
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* scaling POINTs */
point->X *= scale_x;
point->Y *= scale_y;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* scaling LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
x *= scale_x;
y *= scale_y;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* scaling POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* scaling the 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);
}
x *= scale_x;
y *= scale_y;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* scaling the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
x *= scale_x;
y *= scale_y;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE void
gaiaRotateCoords (gaiaGeomCollPtr geom, double angle)
{
/* returns a geometry that is the old geometry with required rotation applied to coordinates */
int ib;
int iv;
double x;
double y;
double z;
double m;
double nx;
double ny;
double rad = angle * 0.0174532925199432958;
double cosine = cos (rad);
double sine = sin (rad);
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* shifting POINTs */
x = point->X;
y = point->Y;
point->X = (x * cosine) + (y * sine);
point->Y = (y * cosine) - (x * sine);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* rotating LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
nx = (x * cosine) + (y * sine);
ny = (y * cosine) - (x * sine);
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, nx, ny, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, nx, ny, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, nx, ny, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, nx, ny);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* rotating POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* rotating the 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);
}
nx = (x * cosine) + (y * sine);
ny = (y * cosine) - (x * sine);
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, nx, ny, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, nx, ny, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, nx, ny, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, nx, ny);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* rotating the INTERIOR RINGs */
m = 0.0;
z = 0.0;
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
nx = (x * cosine) + (y * sine);
ny = (y * cosine) - (x * sine);
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, nx, ny, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, nx, ny, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, nx, ny, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, nx, ny);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE void
gaiaReflectCoords (gaiaGeomCollPtr geom, int x_axis, int y_axis)
{
/* returns a geometry that is the old geometry with required reflection applied to coordinates */
int ib;
int iv;
double x;
double y;
double z = 0.0;
double m = 0.0;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* reflecting POINTs */
if (x_axis)
point->X *= -1.0;
if (y_axis)
point->Y *= -1.0;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* reflecting LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
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);
}
if (x_axis)
x *= -1.0;
if (y_axis)
y *= -1.0;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* reflecting POLYGONs */
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* reflecting the 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);
}
if (x_axis)
x *= -1.0;
if (y_axis)
y *= -1.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* reflecting the INTERIOR RINGs */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
if (x_axis)
x *= -1.0;
if (y_axis)
y *= -1.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
GAIAGEO_DECLARE void
gaiaSwapCoords (gaiaGeomCollPtr geom)
{
/* returns a geometry that is the old geometry with swapped x- and y-coordinates */
int ib;
int iv;
double x;
double y;
double z;
double m;
double sv;
gaiaPointPtr point;
gaiaPolygonPtr polyg;
gaiaLinestringPtr line;
gaiaRingPtr ring;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* swapping POINTs */
sv = point->X;
point->X = point->Y;
point->Y = sv;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* swapping LINESTRINGs */
for (iv = 0; iv < line->Points; iv++)
{
m = 0.0;
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);
}
sv = x;
x = y;
y = sv;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (line->Coords, iv, x, y, m);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (line->Coords, iv, x, y);
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* swapping POLYGONs */
m = 0.0;
z = 0.0;
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* shifting the 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);
}
sv = x;
x = y;
y = sv;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* swapping the INTERIOR RINGs */
m = 0.0;
z = 0.0;
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
sv = x;
x = y;
y = sv;
if (ring->DimensionModel == GAIA_XY_Z)
{
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
else if (ring->DimensionModel == GAIA_XY_M)
{
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
else if (ring->DimensionModel == GAIA_XY_Z_M)
{
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
else
{
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
polyg = polyg->Next;
}
gaiaMbrGeometry (geom);
}
libspatialite-5.1.0/src/gaiageo/gg_wkb.c 0000644 0001750 0001750 00000617201 14463127014 015064 0000000 0000000 /*
gg_wkb.c -- Gaia common support for WKB encoded geometries
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
-----------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
static void
ParseWkbPoint (gaiaGeomCollPtr geo)
{
/* decodes a POINT from WKB */
double x;
double y;
if (geo->size < geo->offset + 16)
return;
x = gaiaImport64 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
geo->offset += 16;
gaiaAddPointToGeomColl (geo, x, y);
}
static void
ParseWkbPointZ (gaiaGeomCollPtr geo)
{
/* decodes a POINTZ from WKB */
double x;
double y;
double z;
if (geo->size < geo->offset + 24)
return;
x = gaiaImport64 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
gaiaAddPointToGeomCollXYZ (geo, x, y, z);
}
static void
ParseWkbPointM (gaiaGeomCollPtr geo)
{
/* decodes a POINTM from WKB */
double x;
double y;
double m;
if (geo->size < geo->offset + 24)
return;
x = gaiaImport64 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
gaiaAddPointToGeomCollXYM (geo, x, y, m);
}
static void
ParseWkbPointZM (gaiaGeomCollPtr geo)
{
/* decodes a POINTZM from WKB */
double x;
double y;
double z;
double m;
if (geo->size < geo->offset + 32)
return;
x = gaiaImport64 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 24), geo->endian,
geo->endian_arch);
geo->offset += 32;
gaiaAddPointToGeomCollXYZM (geo, x, y, z, m);
}
static void
ParseWkbLine (gaiaGeomCollPtr geo)
{
/* decodes a LINESTRING from WKB */
int points;
int iv;
double x;
double y;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (16 * points))
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
gaiaSetPoint (line->Coords, iv, x, y);
geo->offset += 16;
}
}
static void
ParseWkbLineZ (gaiaGeomCollPtr geo)
{
/* decodes a LINESTRINGZ from WKB */
int points;
int iv;
double x;
double y;
double z;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (24 * points))
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
geo->offset += 24;
}
}
static void
ParseWkbLineM (gaiaGeomCollPtr geo)
{
/* decodes a LINESTRINGM from WKB */
int points;
int iv;
double x;
double y;
double m;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (24 * points))
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
gaiaSetPointXYM (line->Coords, iv, x, y, m);
geo->offset += 24;
}
}
static void
ParseWkbLineZM (gaiaGeomCollPtr geo)
{
/* decodes a LINESTRINGZM from WKB */
int points;
int iv;
double x;
double y;
double z;
double m;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (32 * points))
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 24), geo->endian,
geo->endian_arch);
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
geo->offset += 32;
}
}
static void
ParseWkbPolygon (gaiaGeomCollPtr geo)
{
/* decodes a POLYGON from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (16 * nverts))
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
geo->offset += 16;
gaiaSetPoint (ring->Coords, iv, x, y);
}
}
}
static void
ParseWkbPolygonZ (gaiaGeomCollPtr geo)
{
/* decodes a POLYGONZ from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double z;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (24 * nverts))
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
}
}
}
static void
ParseWkbPolygonM (gaiaGeomCollPtr geo)
{
/* decodes a POLYGONM from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double m;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (24 * nverts))
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
}
}
}
static void
ParseWkbPolygonZM (gaiaGeomCollPtr geo)
{
/* decodes a POLYGONZM from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double z;
double m;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (32 * nverts))
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 24), geo->endian,
geo->endian_arch);
geo->offset += 32;
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
}
}
}
static void
ParseCompressedWkbLine (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED LINESTRING from WKB */
int points;
int iv;
double x;
double y;
double last_x = 0.0;
double last_y = 0.0;
float fx;
float fy;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (8 * points) + 16)
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
if (iv == 0 || iv == (points - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
geo->offset += 16;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4), geo->endian,
geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
geo->offset += 8;
}
gaiaSetPoint (line->Coords, iv, x, y);
last_x = x;
last_y = y;
}
}
static void
ParseCompressedWkbLineZ (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED LINESTRINGZ from WKB */
int points;
int iv;
double x;
double y;
double z;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
float fx;
float fy;
float fz;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (12 * points) + 24)
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
if (iv == 0 || iv == (points - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4), geo->endian,
geo->endian_arch);
fz = gaiaImportF32 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
z = last_z + fz;
geo->offset += 12;
}
gaiaSetPointXYZ (line->Coords, iv, x, y, z);
last_x = x;
last_y = y;
last_z = z;
}
}
static void
ParseCompressedWkbLineM (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED LINESTRINGM from WKB */
int points;
int iv;
double x;
double y;
double m;
double last_x = 0.0;
double last_y = 0.0;
float fx;
float fy;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (16 * points) + 16)
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
if (iv == 0 || iv == (points - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
geo->offset += 24;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
geo->offset += 16;
}
gaiaSetPointXYM (line->Coords, iv, x, y, m);
last_x = x;
last_y = y;
}
}
static void
ParseCompressedWkbLineZM (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED LINESTRINGZM from WKB */
int points;
int iv;
double x;
double y;
double z;
double m;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
float fx;
float fy;
float fz;
gaiaLinestringPtr line;
if (geo->size < geo->offset + 4)
return;
points =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (20 * points) + 24)
return;
line = gaiaAddLinestringToGeomColl (geo, points);
for (iv = 0; iv < points; iv++)
{
if (iv == 0 || iv == (points - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 24), geo->endian,
geo->endian_arch);
geo->offset += 32;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4), geo->endian,
geo->endian_arch);
fz = gaiaImportF32 (geo->blob + (geo->offset + 8), geo->endian,
geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 12), geo->endian,
geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
z = last_z + fz;
geo->offset += 20;
}
gaiaSetPointXYZM (line->Coords, iv, x, y, z, m);
last_x = x;
last_y = y;
last_z = z;
}
}
static void
ParseCompressedWkbPolygon (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED POLYGON from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double last_x = 0.0;
double last_y = 0.0;
float fx;
float fy;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (8 * nverts) + 16)
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
if (iv == 0 || iv == (nverts - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
geo->offset += 16;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4),
geo->endian, geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
geo->offset += 8;
}
gaiaSetPoint (ring->Coords, iv, x, y);
last_x = x;
last_y = y;
}
}
}
static void
ParseCompressedWkbPolygonZ (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED POLYGONZ from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double z;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
float fx;
float fy;
float fz;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (12 * nverts) + 24)
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
if (iv == 0 || iv == (nverts - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16),
geo->endian, geo->endian_arch);
geo->offset += 24;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4),
geo->endian, geo->endian_arch);
fz = gaiaImportF32 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
z = last_z + fz;
geo->offset += 12;
}
gaiaSetPointXYZ (ring->Coords, iv, x, y, z);
last_x = x;
last_y = y;
last_z = z;
}
}
}
static void
ParseCompressedWkbPolygonM (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED POLYGONM from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double m;
double last_x = 0.0;
double last_y = 0.0;
float fx;
float fy;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (16 * nverts) + 16)
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
if (iv == 0 || iv == (nverts - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 16),
geo->endian, geo->endian_arch);
geo->offset += 24;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4),
geo->endian, geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
geo->offset += 16;
}
gaiaSetPointXYM (ring->Coords, iv, x, y, m);
last_x = x;
last_y = y;
}
}
}
static void
ParseCompressedWkbPolygonZM (gaiaGeomCollPtr geo)
{
/* decodes a COMPRESSED POLYGONZM from WKB */
int rings;
int nverts;
int iv;
int ib;
double x;
double y;
double z;
double m;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
float fx;
float fy;
float fz;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr ring;
if (geo->size < geo->offset + 4)
return;
rings =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (geo->size < geo->offset + 4)
return;
nverts =
gaiaImport32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
geo->offset += 4;
if (geo->size < geo->offset + (20 * nverts) + 24)
return;
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geo, nverts, rings - 1);
ring = polyg->Exterior;
}
else
ring = gaiaAddInteriorRing (polyg, ib - 1, nverts);
for (iv = 0; iv < nverts; iv++)
{
if (iv == 0 || iv == (nverts - 1))
{
/* first and last vertices are uncompressed */
x = gaiaImport64 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
y = gaiaImport64 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
z = gaiaImport64 (geo->blob + (geo->offset + 16),
geo->endian, geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 24),
geo->endian, geo->endian_arch);
geo->offset += 32;
}
else
{
/* any other intermediate vertex is compressed */
fx = gaiaImportF32 (geo->blob + geo->offset, geo->endian,
geo->endian_arch);
fy = gaiaImportF32 (geo->blob + (geo->offset + 4),
geo->endian, geo->endian_arch);
fz = gaiaImportF32 (geo->blob + (geo->offset + 8),
geo->endian, geo->endian_arch);
m = gaiaImport64 (geo->blob + (geo->offset + 12),
geo->endian, geo->endian_arch);
x = last_x + fx;
y = last_y + fy;
z = last_z + fz;
geo->offset += 20;
}
gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m);
last_x = x;
last_y = y;
last_z = z;
}
}
}
static void
ParseWkbGeometry (gaiaGeomCollPtr geo, int isWKB)
{
/* decodes a MULTIxx or GEOMETRYCOLLECTION from SpatiaLite BLOB */
int entities;
int type;
int ie;
if (geo->size < geo->offset + 4)
return;
entities =
gaiaImport32 (geo->blob + geo->offset, geo->endian, geo->endian_arch);
geo->offset += 4;
for (ie = 0; ie < entities; ie++)
{
if (geo->size < geo->offset + 5)
return;
if (isWKB)
{
/* vanilla WKB could be encoded as mixed big-/little-endian sub-items */
if (*(geo->blob + geo->offset) == 0x01)
geo->endian = GAIA_LITTLE_ENDIAN;
else
geo->endian = GAIA_BIG_ENDIAN;
}
type =
gaiaImport32 (geo->blob + geo->offset + 1, geo->endian,
geo->endian_arch);
geo->offset += 5;
switch (type)
{
case GAIA_POINT:
ParseWkbPoint (geo);
break;
case GAIA_POINTZ:
case GAIA_GEOSWKB_POINTZ:
ParseWkbPointZ (geo);
break;
case GAIA_POINTM:
ParseWkbPointM (geo);
break;
case GAIA_POINTZM:
ParseWkbPointZM (geo);
break;
case GAIA_LINESTRING:
ParseWkbLine (geo);
break;
case GAIA_LINESTRINGZ:
case GAIA_GEOSWKB_LINESTRINGZ:
ParseWkbLineZ (geo);
break;
case GAIA_LINESTRINGM:
ParseWkbLineM (geo);
break;
case GAIA_LINESTRINGZM:
ParseWkbLineZM (geo);
break;
case GAIA_POLYGON:
ParseWkbPolygon (geo);
break;
case GAIA_POLYGONZ:
case GAIA_GEOSWKB_POLYGONZ:
ParseWkbPolygonZ (geo);
break;
case GAIA_POLYGONM:
ParseWkbPolygonM (geo);
break;
case GAIA_POLYGONZM:
ParseWkbPolygonZM (geo);
break;
case GAIA_COMPRESSED_LINESTRING:
ParseCompressedWkbLine (geo);
break;
case GAIA_COMPRESSED_LINESTRINGZ:
ParseCompressedWkbLineZ (geo);
break;
case GAIA_COMPRESSED_LINESTRINGM:
ParseCompressedWkbLineM (geo);
break;
case GAIA_COMPRESSED_LINESTRINGZM:
ParseCompressedWkbLineZM (geo);
break;
case GAIA_COMPRESSED_POLYGON:
ParseCompressedWkbPolygon (geo);
break;
case GAIA_COMPRESSED_POLYGONZ:
ParseCompressedWkbPolygonZ (geo);
break;
case GAIA_COMPRESSED_POLYGONM:
ParseCompressedWkbPolygonM (geo);
break;
case GAIA_COMPRESSED_POLYGONZM:
ParseCompressedWkbPolygonZM (geo);
break;
default:
break;
};
}
}
static gaiaGeomCollPtr
doParseTinyPointBlob (const unsigned char *blob, unsigned int size)
{
/* decoding from SpatiaLite TinyPoint BLOB to GEOMETRY */
unsigned char pointType;
int type;
int little_endian;
int endian_arch = gaiaEndianArch ();
gaiaGeomCollPtr geo = NULL;
if (size < 24)
return NULL; /* cannot be an internal BLOB TinyPoint geometry */
if (*(blob + 0) != GAIA_MARK_START)
return NULL; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return NULL; /* failed to recognize END signature */
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return NULL; /* unknown encoding; nor little-endian neither big-endian */
pointType = *(blob + 6);
geo = gaiaAllocGeomColl ();
geo->Srid = gaiaImport32 (blob + 2, little_endian, endian_arch);
geo->endian_arch = (char) endian_arch;
geo->endian = (char) little_endian;
geo->blob = blob;
geo->size = size;
geo->offset = 7;
switch (pointType)
{
/* setting up DimensionModel */
case GAIA_TINYPOINT_XYZ:
type = GAIA_POINTZ;
geo->DimensionModel = GAIA_XY_Z;
break;
case GAIA_TINYPOINT_XYM:
type = GAIA_POINTM;
geo->DimensionModel = GAIA_XY_M;
break;
case GAIA_TINYPOINT_XYZM:
type = GAIA_POINTZM;
geo->DimensionModel = GAIA_XY_Z_M;
break;
default:
type = GAIA_POINT;
geo->DimensionModel = GAIA_XY;
break;
};
switch (type)
{
/* parsing elementary geometries */
case GAIA_POINT:
ParseWkbPoint (geo);
break;
case GAIA_POINTZ:
ParseWkbPointZ (geo);
break;
case GAIA_POINTM:
ParseWkbPointM (geo);
break;
case GAIA_POINTZM:
ParseWkbPointZM (geo);
break;
default:
break;
};
geo->MinX = geo->FirstPoint->X;
geo->MinY = geo->FirstPoint->Y;
geo->MaxX = geo->FirstPoint->X;
geo->MaxY = geo->FirstPoint->Y;
geo->DeclaredType = GAIA_POINT;
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromSpatiaLiteBlobWkbEx (const unsigned char *blob, unsigned int size,
int gpkg_mode, int gpkg_amphibious)
{
/* decoding from SpatiaLite BLOB to GEOMETRY */
int type;
int little_endian;
int endian_arch = gaiaEndianArch ();
gaiaGeomCollPtr geo = NULL;
if (gpkg_amphibious || gpkg_mode)
{
#ifdef ENABLE_GEOPACKAGE /* GEOPACKAGE enabled: supporting GPKG geometries */
if (gaiaIsValidGPB (blob, size))
{
geo = gaiaFromGeoPackageGeometryBlob (blob, size);
if (geo != NULL)
return geo;
}
if (gpkg_mode)
return NULL; /* must accept only GPKG geometries */
#else
;
#endif /* end GEOPACKAGE: supporting GPKG geometries */
}
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
return doParseTinyPointBlob (blob, size);
}
if (size < 45)
return NULL; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return NULL; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return NULL; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return NULL; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return NULL; /* unknown encoding; nor little-endian neither big-endian */
type = gaiaImport32 (blob + 39, little_endian, endian_arch);
geo = gaiaAllocGeomColl ();
geo->Srid = gaiaImport32 (blob + 2, little_endian, endian_arch);
geo->endian_arch = (char) endian_arch;
geo->endian = (char) little_endian;
geo->blob = blob;
geo->size = size;
geo->offset = 43;
switch (type)
{
/* setting up DimensionModel */
case GAIA_POINTZ:
case GAIA_LINESTRINGZ:
case GAIA_POLYGONZ:
case GAIA_MULTIPOINTZ:
case GAIA_MULTILINESTRINGZ:
case GAIA_MULTIPOLYGONZ:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_COMPRESSED_LINESTRINGZ:
case GAIA_COMPRESSED_POLYGONZ:
geo->DimensionModel = GAIA_XY_Z;
break;
case GAIA_POINTM:
case GAIA_LINESTRINGM:
case GAIA_POLYGONM:
case GAIA_MULTIPOINTM:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTIPOLYGONM:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_COMPRESSED_LINESTRINGM:
case GAIA_COMPRESSED_POLYGONM:
geo->DimensionModel = GAIA_XY_M;
break;
case GAIA_POINTZM:
case GAIA_LINESTRINGZM:
case GAIA_POLYGONZM:
case GAIA_MULTIPOINTZM:
case GAIA_MULTILINESTRINGZM:
case GAIA_MULTIPOLYGONZM:
case GAIA_GEOMETRYCOLLECTIONZM:
case GAIA_COMPRESSED_LINESTRINGZM:
case GAIA_COMPRESSED_POLYGONZM:
geo->DimensionModel = GAIA_XY_Z_M;
break;
default:
geo->DimensionModel = GAIA_XY;
break;
};
switch (type)
{
/* parsing elementary geometries */
case GAIA_POINT:
ParseWkbPoint (geo);
break;
case GAIA_POINTZ:
ParseWkbPointZ (geo);
break;
case GAIA_POINTM:
ParseWkbPointM (geo);
break;
case GAIA_POINTZM:
ParseWkbPointZM (geo);
break;
case GAIA_LINESTRING:
ParseWkbLine (geo);
break;
case GAIA_LINESTRINGZ:
ParseWkbLineZ (geo);
break;
case GAIA_LINESTRINGM:
ParseWkbLineM (geo);
break;
case GAIA_LINESTRINGZM:
ParseWkbLineZM (geo);
break;
case GAIA_POLYGON:
ParseWkbPolygon (geo);
break;
case GAIA_POLYGONZ:
ParseWkbPolygonZ (geo);
break;
case GAIA_POLYGONM:
ParseWkbPolygonM (geo);
break;
case GAIA_POLYGONZM:
ParseWkbPolygonZM (geo);
break;
case GAIA_COMPRESSED_LINESTRING:
ParseCompressedWkbLine (geo);
break;
case GAIA_COMPRESSED_LINESTRINGZ:
ParseCompressedWkbLineZ (geo);
break;
case GAIA_COMPRESSED_LINESTRINGM:
ParseCompressedWkbLineM (geo);
break;
case GAIA_COMPRESSED_LINESTRINGZM:
ParseCompressedWkbLineZM (geo);
break;
case GAIA_COMPRESSED_POLYGON:
ParseCompressedWkbPolygon (geo);
break;
case GAIA_COMPRESSED_POLYGONZ:
ParseCompressedWkbPolygonZ (geo);
break;
case GAIA_COMPRESSED_POLYGONM:
ParseCompressedWkbPolygonM (geo);
break;
case GAIA_COMPRESSED_POLYGONZM:
ParseCompressedWkbPolygonZM (geo);
break;
case GAIA_MULTIPOINT:
case GAIA_MULTIPOINTZ:
case GAIA_MULTIPOINTM:
case GAIA_MULTIPOINTZM:
case GAIA_MULTILINESTRING:
case GAIA_MULTILINESTRINGZ:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTILINESTRINGZM:
case GAIA_MULTIPOLYGON:
case GAIA_MULTIPOLYGONZ:
case GAIA_MULTIPOLYGONM:
case GAIA_MULTIPOLYGONZM:
case GAIA_GEOMETRYCOLLECTION:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_GEOMETRYCOLLECTIONZM:
ParseWkbGeometry (geo, 0);
break;
default:
break;
};
geo->MinX = gaiaImport64 (blob + 6, little_endian, endian_arch);
geo->MinY = gaiaImport64 (blob + 14, little_endian, endian_arch);
geo->MaxX = gaiaImport64 (blob + 22, little_endian, endian_arch);
geo->MaxY = gaiaImport64 (blob + 30, little_endian, endian_arch);
switch (type)
{
/* setting up DeclaredType */
case GAIA_POINT:
case GAIA_POINTZ:
case GAIA_POINTM:
case GAIA_POINTZM:
geo->DeclaredType = GAIA_POINT;
break;
case GAIA_LINESTRING:
case GAIA_LINESTRINGZ:
case GAIA_LINESTRINGM:
case GAIA_LINESTRINGZM:
case GAIA_COMPRESSED_LINESTRING:
case GAIA_COMPRESSED_LINESTRINGZ:
case GAIA_COMPRESSED_LINESTRINGM:
case GAIA_COMPRESSED_LINESTRINGZM:
geo->DeclaredType = GAIA_LINESTRING;
break;
case GAIA_POLYGON:
case GAIA_POLYGONZ:
case GAIA_POLYGONM:
case GAIA_POLYGONZM:
case GAIA_COMPRESSED_POLYGON:
case GAIA_COMPRESSED_POLYGONZ:
case GAIA_COMPRESSED_POLYGONM:
case GAIA_COMPRESSED_POLYGONZM:
geo->DeclaredType = GAIA_POLYGON;
break;
case GAIA_MULTIPOINT:
case GAIA_MULTIPOINTZ:
case GAIA_MULTIPOINTM:
case GAIA_MULTIPOINTZM:
geo->DeclaredType = GAIA_MULTIPOINT;
break;
case GAIA_MULTILINESTRING:
case GAIA_MULTILINESTRINGZ:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTILINESTRINGZM:
geo->DeclaredType = GAIA_MULTILINESTRING;
break;
case GAIA_MULTIPOLYGON:
case GAIA_MULTIPOLYGONZ:
case GAIA_MULTIPOLYGONM:
case GAIA_MULTIPOLYGONZM:
geo->DeclaredType = GAIA_MULTIPOLYGON;
break;
case GAIA_GEOMETRYCOLLECTION:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_GEOMETRYCOLLECTIONZM:
geo->DeclaredType = GAIA_GEOMETRYCOLLECTION;
break;
default:
geo->DeclaredType = GAIA_UNKNOWN;
break;
};
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromSpatiaLiteBlobWkb (const unsigned char *blob, unsigned int size)
{
/*
* decoding from SpatiaLite BLOB to GEOMETRY
* convenience method - always disabling GPKG compatibility Modes
*/
return gaiaFromSpatiaLiteBlobWkbEx (blob, size, 0, 0);
}
static gaiaGeomCollPtr
doParseTinyPointBlobMbr (const unsigned char *blob, unsigned int size)
{
/* decoding from SpatiaLite TinyPoint BLOB (MBR only) */
int little_endian;
int endian_arch = gaiaEndianArch ();
double x;
double y;
gaiaGeomCollPtr geo = NULL;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
if (size < 24)
return NULL; /* cannot be an internal BLOB TinyPoint geometry */
if (*(blob + 0) != GAIA_MARK_START)
return NULL; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return NULL; /* failed to recognize END signature */
if (*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
little_endian = 0;
else
return NULL; /* unknown encoding; nor little-endian neither big-endian */
x = gaiaImport64 (blob + 7, little_endian, endian_arch);
y = gaiaImport64 (blob + 15, little_endian, endian_arch);
geo = gaiaAllocGeomColl ();
polyg = gaiaAddPolygonToGeomColl (geo, 5, 0);
ring = polyg->Exterior;
gaiaSetPoint (ring->Coords, 0, x, y); /* vertex # 1 */
gaiaSetPoint (ring->Coords, 1, x, y); /* vertex # 2 */
gaiaSetPoint (ring->Coords, 2, x, y); /* vertex # 3 */
gaiaSetPoint (ring->Coords, 3, x, y); /* vertex # 4 */
gaiaSetPoint (ring->Coords, 4, x, y); /* vertex # 5 [same as vertex # 1 to close the polygon] */
return geo;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromSpatiaLiteBlobMbr (const unsigned char *blob, unsigned int size)
{
/* decoding from SpatiaLite BLOB to GEOMETRY [MBR only] */
int little_endian;
int endian_arch = gaiaEndianArch ();
double minx;
double miny;
double maxx;
double maxy;
gaiaGeomCollPtr geo = NULL;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
if (size == 24 || size == 32 || size == 40)
{
/* testing for a possible TinyPoint BLOB */
if (*(blob + 0) == GAIA_MARK_START &&
(*(blob + 1) == GAIA_TINYPOINT_LITTLE_ENDIAN
|| *(blob + 1) == GAIA_TINYPOINT_BIG_ENDIAN)
&& *(blob + (size - 1)) == GAIA_MARK_END)
return doParseTinyPointBlobMbr (blob, size);
}
if (size < 45)
return NULL; /* cannot be an internal BLOB WKB geometry */
if (*(blob + 0) != GAIA_MARK_START)
return NULL; /* failed to recognize START signature */
if (*(blob + (size - 1)) != GAIA_MARK_END)
return NULL; /* failed to recognize END signature */
if (*(blob + 38) != GAIA_MARK_MBR)
return NULL; /* failed to recognize MBR signature */
if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
little_endian = 1;
else if (*(blob + 1) == GAIA_BIG_ENDIAN)
little_endian = 0;
else
return NULL; /* unknown encoding; nor litte-endian neither big-endian */
geo = gaiaAllocGeomColl ();
polyg = gaiaAddPolygonToGeomColl (geo, 5, 0);
ring = polyg->Exterior;
minx = gaiaImport64 (blob + 6, little_endian, endian_arch);
miny = gaiaImport64 (blob + 14, little_endian, endian_arch);
maxx = gaiaImport64 (blob + 22, little_endian, endian_arch);
maxy = gaiaImport64 (blob + 30, little_endian, endian_arch);
gaiaSetPoint (ring->Coords, 0, minx, miny); /* vertex # 1 */
gaiaSetPoint (ring->Coords, 1, maxx, miny); /* vertex # 2 */
gaiaSetPoint (ring->Coords, 2, maxx, maxy); /* vertex # 3 */
gaiaSetPoint (ring->Coords, 3, minx, maxy); /* vertex # 4 */
gaiaSetPoint (ring->Coords, 4, minx, miny); /* vertex # 5 [same as vertex # 1 to close the polygon] */
return geo;
}
GAIAGEO_DECLARE void
gaiaToSpatiaLiteBlobWkbEx (gaiaGeomCollPtr geom, unsigned char **result,
int *size, int gpkg_mode)
{
/* simply defaults to gaiaToSpatiaLiteBlobWkbEx2 tiny_point=FALSE */
gaiaToSpatiaLiteBlobWkbEx2 (geom, result, size, gpkg_mode, 0);
}
static void
doEncodeTinyPointBlob (gaiaGeomCollPtr geom, unsigned char **result, int *size)
{
/* encoding a TinyPoint BLOB */
int sz;
unsigned char *blob;
unsigned char *ptr;
int endian_arch = gaiaEndianArch ();
gaiaPointPtr point = geom->FirstPoint;
/* compunting the BLOB size */
if (geom->DimensionModel == GAIA_XY_Z)
sz = 32;
else if (geom->DimensionModel == GAIA_XY_M)
sz = 32;
else if (geom->DimensionModel == GAIA_XY_Z_M)
sz = 40;
else
sz = 24;
/* allocating the BLOB */
blob = malloc (sz);
ptr = blob;
/* and finally we build the BLOB */
*ptr = GAIA_MARK_START; /* START signature */
ptr++;
*(ptr) = GAIA_TINYPOINT_LITTLE_ENDIAN; /* byte ordering */
ptr++;
gaiaExport32 (ptr, geom->Srid, 1, endian_arch); /* the SRID */
ptr += 4;
if (geom->DimensionModel == GAIA_XY_Z)
*ptr = GAIA_TINYPOINT_XYZ;
else if (geom->DimensionModel == GAIA_XY_M)
*ptr = GAIA_TINYPOINT_XYM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
*ptr = GAIA_TINYPOINT_XYZM;
else
*ptr = GAIA_TINYPOINT_XY;
ptr++;
gaiaExport64 (ptr, point->X, 1, endian_arch); /* X */
ptr += 8;
gaiaExport64 (ptr, point->Y, 1, endian_arch); /* Y */
ptr += 8;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (ptr, point->Z, 1, endian_arch); /* Z */
ptr += 8;
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, point->M, 1, endian_arch); /* M */
ptr += 8;
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (ptr, point->Z, 1, endian_arch); /* Z */
ptr += 8;
gaiaExport64 (ptr, point->M, 1, endian_arch); /* M */
ptr += 8;
}
*ptr = GAIA_MARK_END; /* END signature */
*result = blob;
*size = sz;
}
GAIAGEO_DECLARE void
gaiaToSpatiaLiteBlobWkbEx2 (gaiaGeomCollPtr geom, unsigned char **result,
int *size, int gpkg_mode, int tiny_point)
{
/* builds the SpatiaLite BLOB representation for this GEOMETRY */
int ib;
int iv;
double x;
double y;
double z = 0.0;
double m = 0.0;
int entities = 0;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int type;
unsigned char *ptr;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
int endian_arch = gaiaEndianArch ();
gaiaMbrGeometry (geom);
if (gpkg_mode)
{
#ifdef ENABLE_GEOPACKAGE /* only if GeoPackage support is enabled */
/* GeoPackage Mode enabled */
gaiaToGPB (geom, result, size);
#endif /* end GEOPACKAGE conditional */
return;
}
/* how many entities, and of what kind, do we have ? */
pt = geom->FirstPoint;
while (pt)
{
point = pt;
entities++;
n_points++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
line = ln;
entities++;
n_linestrings++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
polyg = pg;
entities++;
n_polygons++;
pg = pg->Next;
}
*size = 0;
*result = NULL;
if (n_points == 0 && n_polygons == 0 && n_linestrings == 0)
return;
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0 && entities == 1
&& geom->DeclaredType != GAIA_MULTIPOINT
&& geom->DeclaredType != GAIA_GEOMETRYCOLLECTION && tiny_point)
{
/* using the TinyPoint BLOB encoding */
doEncodeTinyPointBlob (geom, result, size);
return;
}
/* ok, we can determine the geometry class */
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POINTZM;
else
type = GAIA_POINT;
}
}
else if (n_points > 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
}
else if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_LINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_LINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_LINESTRINGZM;
else
type = GAIA_LINESTRING;
}
}
else if (n_points == 0 && n_linestrings > 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POLYGONZM;
else
type = GAIA_POLYGON;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
/* and now we compute the size of BLOB */
*size = 44; /* header size */
switch (type)
{
case GAIA_POINT:
*size += (sizeof (double) * 2); /* [x,y] coords */
break;
case GAIA_POINTZ:
*size += (sizeof (double) * 3); /* [x,y,z] coords */
break;
case GAIA_POINTM:
*size += (sizeof (double) * 3); /* [x,y,m] coords */
break;
case GAIA_POINTZM:
*size += (sizeof (double) * 4); /* [x,y,z,m] coords */
break;
case GAIA_LINESTRING:
*size += (4 + ((sizeof (double) * 2) * line->Points)); /* # points + [x,y] for each vertex */
break;
case GAIA_LINESTRINGZ:
*size += (4 + ((sizeof (double) * 3) * line->Points)); /* # points + [x,y,z] for each vertex */
break;
case GAIA_LINESTRINGM:
*size += (4 + ((sizeof (double) * 3) * line->Points)); /* # points + [x,y,m] for each vertex */
break;
case GAIA_LINESTRINGZM:
*size += (4 + ((sizeof (double) * 4) * line->Points)); /* # points + [x,y,z,m] for each vertex */
break;
case GAIA_POLYGON:
rng = polyg->Exterior;
*size += (8 + ((sizeof (double) * 2) * rng->Points)); /* # rings + # points + [x.y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + ((sizeof (double) * 2) * rng->Points)); /* # points + [x,y] array - interior ring */
}
break;
case GAIA_POLYGONZ:
rng = polyg->Exterior;
*size += (8 + ((sizeof (double) * 3) * rng->Points)); /* # rings + # points + [x,y,z] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + ((sizeof (double) * 3) * rng->Points)); /* # points + [x,y,z] array - interior ring */
}
break;
case GAIA_POLYGONM:
rng = polyg->Exterior;
*size += (8 + ((sizeof (double) * 3) * rng->Points)); /* # rings + # points + [x,y,m] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + ((sizeof (double) * 3) * rng->Points)); /* # points + [x,y,m] array - interior ring */
}
break;
case GAIA_POLYGONZM:
rng = polyg->Exterior;
*size += (8 + ((sizeof (double) * 4) * rng->Points)); /* # rings + # points + [x,y,z,m] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + ((sizeof (double) * 4) * rng->Points)); /* # points + [x,y,z,m] array - interior ring */
}
break;
default:
/* this one is not a simple geometry; should be a MULTIxxxx or a GEOMETRYCOLLECTION */
*size += 4; /* # entities */
point = geom->FirstPoint;
while (point)
{
*size += 5; /* entity header */
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (sizeof (double) * 3); /* three doubles for each POINT */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (sizeof (double) * 4); /* four doubles for each POINT */
else
*size += (sizeof (double) * 2); /* two doubles for each POINT */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
*size += 5; /* entity header */
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (4 + ((sizeof (double) * 3) * line->Points)); /* # points + [x,y,z] for each vertex */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + ((sizeof (double) * 4) * line->Points)); /* # points + [x,y,z,m] for each vertex */
else
*size += (4 + ((sizeof (double) * 2) * line->Points)); /* # points + [x,y] for each vertex */
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
*size += 5; /* entity header */
rng = polyg->Exterior;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (8 + ((sizeof (double) * 3) * rng->Points)); /* # rings + # points + [x,y,z] array - exterior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (8 + ((sizeof (double) * 4) * rng->Points)); /* # rings + # points + [x,y,z,m] array - exterior ring */
else
*size += (8 + ((sizeof (double) * 2) * rng->Points)); /* # rings + # points + [x,y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (4 + ((sizeof (double) * 3) * rng->Points)); /* # points + [x,y,z] array - interior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + ((sizeof (double) * 4) * rng->Points)); /* # points + [x,y,z,m] array - interior ring */
else
*size += (4 + ((sizeof (double) * 2) * rng->Points)); /* # points + [x,y] array - interior ring */
}
polyg = polyg->Next;
}
};
*result = malloc (*size);
ptr = *result;
/* and finally we build the BLOB */
switch (type)
{
case GAIA_POINT:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
*(ptr + 59) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZ, 1, endian_arch); /* class POINT XYZ */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->Z, 1, endian_arch); /* Z */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTM, 1, endian_arch); /* class POINT XYM */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->M, 1, endian_arch); /* M */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZM, 1, endian_arch); /* class POINT XYZM */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->Z, 1, endian_arch); /* M */
gaiaExport64 (ptr + 67, point->M, 1, endian_arch); /* Z */
*(ptr + 75) = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRING:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_LINESTRING, 1, endian_arch); /* class LINESTRING */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPoint (line->Coords, iv, &x, &y);
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
ptr += 16;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_LINESTRINGZ, 1, endian_arch); /* class LINESTRING XYZ */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
ptr += 24;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_LINESTRINGM, 1, endian_arch); /* class LINESTRING XYM */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, m, 1, endian_arch);
ptr += 24;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_LINESTRINGZM, 1, endian_arch); /* class LINESTRING XYZM */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
gaiaExport64 (ptr + 24, m, 1, endian_arch);
ptr += 32;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGON:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POLYGON, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
ptr += 16;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
ptr += 16;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POLYGONZ, 1, endian_arch); /* class POLYGON XYZ */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
gaiaExport64 (ptr + 16, z, 1, endian_arch); /* Z - exterior ring */
ptr += 24;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
gaiaExport64 (ptr + 16, z, 1, endian_arch); /* Z - interior ring */
ptr += 24;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POLYGONM, 1, endian_arch); /* class POLYGON XYM */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
gaiaExport64 (ptr + 16, m, 1, endian_arch); /* M - exterior ring */
ptr += 24;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
gaiaExport64 (ptr + 16, m, 1, endian_arch); /* M - interior ring */
ptr += 24;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POLYGONZM, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
gaiaExport64 (ptr + 16, z, 1, endian_arch); /* Z - exterior ring */
gaiaExport64 (ptr + 24, m, 1, endian_arch); /* M - exterior ring */
ptr += 32;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
gaiaExport64 (ptr + 16, z, 1, endian_arch); /* Z - exterior ring */
gaiaExport64 (ptr + 24, m, 1, endian_arch); /* M - exterior ring */
ptr += 32;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
default:
/* this one is a MULTIxxxx or a GEOMETRYCOLLECTION - building the main header */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, type, 1, endian_arch); /* geometric class */
gaiaExport32 (ptr + 43, entities, 1, endian_arch); /* # entities */
ptr += 47;
point = geom->FirstPoint;
while (point)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport32 (ptr + 1, GAIA_POINTZ, 1, endian_arch); /* class POINT XYZ */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->Z, 1, endian_arch); /* Z */
ptr += 29;
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport32 (ptr + 1, GAIA_POINTM, 1, endian_arch); /* class POINT XYM */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->M, 1, endian_arch); /* M */
ptr += 29;
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport32 (ptr + 1, GAIA_POINTZM, 1, endian_arch); /* class POINT XYZM */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->Z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 29, point->M, 1, endian_arch); /* M */
ptr += 37;
}
else
{
gaiaExport32 (ptr + 1, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
ptr += 21;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGZ, 1, endian_arch); /* class LINESTRING XYZ */
else if (geom->DimensionModel == GAIA_XY_M)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGM, 1, endian_arch); /* class LINESTRING XYM */
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGZM, 1, endian_arch); /* class LINESTRING XYZM */
else
gaiaExport32 (ptr + 1, GAIA_LINESTRING, 1, endian_arch); /* class LINESTRING */
gaiaExport32 (ptr + 5, line->Points, 1, endian_arch); /* # points */
ptr += 9;
for (iv = 0; iv < line->Points; iv++)
{
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y */
ptr += 16;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M */
ptr += 16;
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaExport32 (ptr + 1, GAIA_POLYGONZ, 1, endian_arch); /* class POLYGON XYZ */
else if (geom->DimensionModel == GAIA_XY_M)
gaiaExport32 (ptr + 1, GAIA_POLYGONM, 1, endian_arch); /* class POLYGON XYM */
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaExport32 (ptr + 1, GAIA_POLYGONZM, 1, endian_arch); /* class POLYGON XYZM */
else
gaiaExport32 (ptr + 1, GAIA_POLYGON, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 5, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 9, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 13;
for (iv = 0; iv < rng->Points; iv++)
{
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
ptr += 16;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M */
ptr += 16;
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y,
&z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
ptr += 16;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M */
ptr += 16;
}
}
}
polyg = polyg->Next;
}
*ptr = GAIA_MARK_END; /* END signature */
};
}
GAIAGEO_DECLARE void
gaiaToSpatiaLiteBlobWkb (gaiaGeomCollPtr geom, unsigned char **result,
int *size)
{
/*
* builds the SpatiaLite BLOB representation for this GEOMETRY
* convenience method - always disabling GPKG compatibility Modes
*/
gaiaToSpatiaLiteBlobWkbEx (geom, result, size, 0);
}
GAIAGEO_DECLARE void
gaiaToCompressedBlobWkb (gaiaGeomCollPtr geom, unsigned char **result,
int *size)
{
/*
/ builds the SpatiaLite BLOB representation for this GEOMETRY
/ geometry-compression will be applied to LINESTRINGs and RINGs
*/
int ib;
int iv;
double x;
double y;
double z;
double m;
double last_x = 0.0;
double last_y = 0.0;
double last_z = 0.0;
float fx;
float fy;
float fz;
int entities = 0;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int type;
unsigned char *ptr;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
int endian_arch = gaiaEndianArch ();
gaiaMbrGeometry (geom);
/* how many entities, and of what kind, do we have ? */
pt = geom->FirstPoint;
while (pt)
{
point = pt;
entities++;
n_points++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
line = ln;
entities++;
n_linestrings++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
polyg = pg;
entities++;
n_polygons++;
pg = pg->Next;
}
*size = 0;
*result = NULL;
if (n_points == 0 && n_polygons == 0 && n_linestrings == 0)
return;
/* ok, we can determine the geometry class */
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POINTZM;
else
type = GAIA_POINT;
}
}
else if (n_points > 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
}
else if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_LINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_LINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_LINESTRINGZM;
else
type = GAIA_LINESTRING;
}
}
else if (n_points == 0 && n_linestrings > 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POLYGONZM;
else
type = GAIA_POLYGON;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
/* and now we compute the size of BLOB */
*size = 44; /* header size */
switch (type)
{
case GAIA_POINT:
*size += (sizeof (double) * 2); /* [x,y] coords */
break;
case GAIA_POINTZ:
*size += (sizeof (double) * 3); /* [x,y,z] coords */
break;
case GAIA_POINTM:
*size += (sizeof (double) * 3); /* [x,y,m] coords */
break;
case GAIA_POINTZM:
*size += (sizeof (double) * 4); /* [x,y,z,m] coords */
break;
case GAIA_LINESTRING:
*size += (4 + (8 * line->Points) + 16); /* # points + [x,y] for each vertex */
break;
case GAIA_LINESTRINGZ:
*size += (4 + (12 * line->Points) + 24); /* # points + [x,y,z] for each vertex */
break;
case GAIA_LINESTRINGM:
*size += (4 + (16 * line->Points) + 16); /* # points + [x,y,m] for each vertex */
break;
case GAIA_LINESTRINGZM:
*size += (4 + (20 * line->Points) + 24); /* # points + [x,y,z,m] for each vertex */
break;
case GAIA_POLYGON:
rng = polyg->Exterior;
*size += (8 + (8 * rng->Points) + 16); /* # rings + # points + [x.y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + (8 * rng->Points) + 16); /* # points + [x,y] array - interior ring */
}
break;
case GAIA_POLYGONZ:
rng = polyg->Exterior;
*size += (8 + (12 * rng->Points) + 24); /* # rings + # points + [x,y,z] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + (12 * rng->Points) + 24); /* # points + [x,y,z] array - interior ring */
}
break;
case GAIA_POLYGONM:
rng = polyg->Exterior;
*size += (8 + (16 * rng->Points) + 16); /* # rings + # points + [x,y,m] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + (16 * rng->Points) + 16); /* # points + [x,y,m] array - interior ring */
}
break;
case GAIA_POLYGONZM:
rng = polyg->Exterior;
*size += (8 + (20 * rng->Points) + 24); /* # rings + # points + [x,y,z,m] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
*size += (4 + (20 * rng->Points) + 24); /* # points + [x,y,z,m] array - interior ring */
}
break;
default:
/* this one is not a simple geometry; should be a MULTIxxxx or a GEOMETRYCOLLECTION */
*size += 4; /* # entities */
point = geom->FirstPoint;
while (point)
{
*size += 5; /* entity header */
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (sizeof (double) * 3); /* three doubles for each POINT */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (sizeof (double) * 4); /* four doubles for each POINT */
else
*size += (sizeof (double) * 2); /* two doubles for each POINT */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
*size += 5; /* entity header */
if (geom->DimensionModel == GAIA_XY_Z)
*size += (4 + (12 * line->Points) + 24); /* # points + [x,y,z] for each vertex */
else if (geom->DimensionModel == GAIA_XY_M)
*size += (4 + (16 * line->Points) + 16); /* # points + [x,y,m] for each vertex */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + (20 * line->Points) + 24); /* # points + [x,y,z,m] for each vertex */
else
*size += (4 + (8 * line->Points) + 16); /* # points + [x,y] for each vertex */
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
*size += 5; /* entity header */
rng = polyg->Exterior;
if (geom->DimensionModel == GAIA_XY_Z)
*size += (8 + (12 * rng->Points) + 24); /* # rings + # points + [x,y,z] array - exterior ring */
else if (geom->DimensionModel == GAIA_XY_M)
*size += (8 + (16 * rng->Points) + 16); /* # rings + # points + [x,y,m] array - exterior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (8 + (20 * rng->Points) + 24); /* # rings + # points + [x,y,z,m] array - exterior ring */
else
*size += (8 + (8 * rng->Points) + 16); /* # rings + # points + [x,y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
if (geom->DimensionModel == GAIA_XY_Z)
*size += (4 + (12 * rng->Points) + 24); /* # points + [x,y,z] array - interior ring */
else if (geom->DimensionModel == GAIA_XY_M)
*size += (4 + (16 * rng->Points) + 16); /* # points + [x,y,m] array - interior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + (20 * rng->Points) + 24); /* # points + [x,y,z,m] array - interior ring */
else
*size += (4 + (8 * rng->Points) + 16); /* # points + [x,y] array - interior ring */
}
polyg = polyg->Next;
}
};
*result = malloc (*size);
ptr = *result;
/* and finally we build the BLOB */
switch (type)
{
case GAIA_POINT:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
*(ptr + 59) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZ, 1, endian_arch); /* class POINT XYZ */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->Z, 1, endian_arch); /* Z */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTM, 1, endian_arch); /* class POINT XYM */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->M, 1, endian_arch); /* M */
*(ptr + 67) = GAIA_MARK_END; /* END signature */
break;
case GAIA_POINTZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_POINTZM, 1, endian_arch); /* class POINT XYZM */
gaiaExport64 (ptr + 43, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 51, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 59, point->Z, 1, endian_arch); /* M */
gaiaExport64 (ptr + 67, point->M, 1, endian_arch); /* Z */
*(ptr + 75) = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRING:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_LINESTRING, 1, endian_arch); /* class LINESTRING */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPoint (line->Coords, iv, &x, &y);
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
ptr += 8;
}
last_x = x;
last_y = y;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_LINESTRINGZ, 1, endian_arch); /* class LINESTRING XYZ */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
ptr += 12;
}
last_x = x;
last_y = y;
last_z = z;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_LINESTRINGM, 1, endian_arch); /* class LINESTRING XYM */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, m, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExport64 (ptr + 8, m, 1, endian_arch);
ptr += 16;
}
last_x = x;
last_y = y;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_LINESTRINGZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_LINESTRINGZM, 1, endian_arch); /* class LINESTRING XYZM */
gaiaExport32 (ptr + 43, line->Points, 1, endian_arch); /* # points */
ptr += 47;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
gaiaExport64 (ptr + 24, m, 1, endian_arch);
ptr += 32;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
gaiaExport64 (ptr + 12, m, 1, endian_arch);
ptr += 20;
}
last_x = x;
last_y = y;
last_z = z;
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGON:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_POLYGON, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
ptr += 8;
}
last_x = x;
last_y = y;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
ptr += 8;
}
last_x = x;
last_y = y;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONZ:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_POLYGONZ, 1, endian_arch); /* class POLYGON XYZ */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
ptr += 12;
}
last_x = x;
last_y = y;
last_z = z;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
ptr += 12;
}
last_x = x;
last_y = y;
last_z = z;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_POLYGONM, 1, endian_arch); /* class POLYGON XYM */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, m, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExport64 (ptr + 8, m, 1, endian_arch);
ptr += 16;
}
last_x = x;
last_y = y;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, m, 1, endian_arch);
ptr += 24;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExport64 (ptr + 8, m, 1, endian_arch);
ptr += 16;
}
last_x = x;
last_y = y;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
case GAIA_POLYGONZM:
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, GAIA_COMPRESSED_POLYGONZM, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 43, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 47, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 51;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
gaiaExport64 (ptr + 24, m, 1, endian_arch);
ptr += 32;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
gaiaExport64 (ptr + 12, m, 1, endian_arch);
ptr += 20;
}
last_x = x;
last_y = y;
last_z = z;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch);
gaiaExport64 (ptr + 8, y, 1, endian_arch);
gaiaExport64 (ptr + 16, z, 1, endian_arch);
gaiaExport64 (ptr + 24, m, 1, endian_arch);
ptr += 32;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fx, 1, endian_arch);
gaiaExportF32 (ptr + 4, fy, 1, endian_arch);
gaiaExportF32 (ptr + 8, fz, 1, endian_arch);
gaiaExport64 (ptr + 12, m, 1, endian_arch);
ptr += 20;
}
last_x = x;
last_y = y;
last_z = z;
}
}
*ptr = GAIA_MARK_END; /* END signature */
break;
default:
/* this one is a MULTIxxxx or a GEOMETRYCOLLECTION - building the main header */
*ptr = GAIA_MARK_START; /* START signature */
*(ptr + 1) = GAIA_LITTLE_ENDIAN; /* byte ordering */
gaiaExport32 (ptr + 2, geom->Srid, 1, endian_arch); /* the SRID */
gaiaExport64 (ptr + 6, geom->MinX, 1, endian_arch); /* MBR - minimum X */
gaiaExport64 (ptr + 14, geom->MinY, 1, endian_arch); /* MBR - minimum Y */
gaiaExport64 (ptr + 22, geom->MaxX, 1, endian_arch); /* MBR - maximum X */
gaiaExport64 (ptr + 30, geom->MaxY, 1, endian_arch); /* MBR - maximum Y */
*(ptr + 38) = GAIA_MARK_MBR; /* MBR signature */
gaiaExport32 (ptr + 39, type, 1, endian_arch); /* geometric class */
gaiaExport32 (ptr + 43, entities, 1, endian_arch); /* # entities */
ptr += 47;
point = geom->FirstPoint;
while (point)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport32 (ptr + 1, GAIA_POINTZ, 1, endian_arch); /* class POINT XYZ */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->Z, 1, endian_arch); /* Z */
ptr += 29;
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport32 (ptr + 1, GAIA_POINTM, 1, endian_arch); /* class POINT XYM */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->M, 1, endian_arch); /* M */
ptr += 29;
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport32 (ptr + 1, GAIA_POINTZM, 1, endian_arch); /* class POINT XYZM */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
gaiaExport64 (ptr + 21, point->Z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 29, point->M, 1, endian_arch); /* M */
ptr += 37;
}
else
{
gaiaExport32 (ptr + 1, GAIA_POINT, 1, endian_arch); /* class POINT */
gaiaExport64 (ptr + 5, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 13, point->Y, 1, endian_arch); /* Y */
ptr += 21;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_LINESTRINGZ, 1, endian_arch); /* class LINESTRING XYZ */
else if (geom->DimensionModel == GAIA_XY_M)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_LINESTRINGM, 1, endian_arch); /* class LINESTRING XYM */
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_LINESTRINGZM, 1, endian_arch); /* class LINESTRING XYZM */
else
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_LINESTRING, 1, endian_arch); /* class LINESTRING */
gaiaExport32 (ptr + 5, line->Points, 1, endian_arch); /* # points */
ptr += 9;
for (iv = 0; iv < line->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y */
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch); /* X */
gaiaExportF32 (ptr + 4, fy, 1, endian_arch); /* Y */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z)
{
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (iv == 0 || iv == (line->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
last_x = x;
last_y = y;
last_z = z;
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
*ptr = GAIA_MARK_ENTITY; /* ENTITY signature */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_POLYGONZ, 1, endian_arch); /* class POLYGON XYZ */
else if (geom->DimensionModel == GAIA_XY_M)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_POLYGONM, 1, endian_arch); /* class POLYGON XYM */
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_POLYGONZM, 1, endian_arch); /* class POLYGON XYZM */
else
gaiaExport32 (ptr + 1, GAIA_COMPRESSED_POLYGON, 1, endian_arch); /* class POLYGON */
gaiaExport32 (ptr + 5, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 9, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 13;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch); /* X */
gaiaExportF32 (ptr + 4, fy, 1, endian_arch); /* Y */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z)
{
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
last_x = x;
last_y = y;
last_z = z;
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z,
&m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
ptr += 16;
}
else
{
/* compressing any other intermediate vertex */
fx = (float) (x - last_x);
fy = (float) (y - last_y);
gaiaExportF32 (ptr, fx, 1, endian_arch); /* X */
gaiaExportF32 (ptr + 4, fy, 1, endian_arch); /* Y */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z)
{
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
}
if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (geom->DimensionModel == GAIA_XY_Z_M)
{
if (iv == 0 || iv == (rng->Points - 1))
{
/* first and last vertices are uncompressed */
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
else
{
/* compressing any other intermediate vertex */
fz = (float) (z - last_z);
gaiaExportF32 (ptr, fz, 1, endian_arch); /* Z */
ptr += 4;
}
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
last_x = x;
last_y = y;
last_z = z;
}
}
polyg = polyg->Next;
}
*ptr = GAIA_MARK_END; /* END signature */
};
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromWkb (const unsigned char *blob, unsigned int size)
{
/* decoding from WKB to GEOMETRY */
int type;
int little_endian;
gaiaGeomCollPtr geo = NULL;
int endian_arch = gaiaEndianArch ();
if (size < 5)
return NULL;
if (*(blob + 0) == 0x01)
little_endian = GAIA_LITTLE_ENDIAN;
else
little_endian = GAIA_BIG_ENDIAN;
type = gaiaImport32 (blob + 1, little_endian, endian_arch);
if (type == GAIA_POINTZ || type == GAIA_LINESTRINGZ || type == GAIA_POLYGONZ
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_GEOSWKB_POINTZ || type == GAIA_GEOSWKB_LINESTRINGZ
|| type == GAIA_GEOSWKB_POLYGONZ || type == GAIA_GEOSWKB_MULTIPOINTZ
|| type == GAIA_GEOSWKB_MULTILINESTRINGZ
|| type == GAIA_GEOSWKB_MULTIPOLYGONZ
|| type == GAIA_GEOSWKB_GEOMETRYCOLLECTIONZ)
geo = gaiaAllocGeomCollXYZ ();
else if (type == GAIA_POINTM || type == GAIA_LINESTRINGM
|| type == GAIA_POLYGONM || type == GAIA_MULTIPOINTM
|| type == GAIA_MULTILINESTRINGM || type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
geo = gaiaAllocGeomCollXYM ();
else if (type == GAIA_POINTZM || type == GAIA_LINESTRINGZM
|| type == GAIA_POLYGONZM || type == GAIA_MULTIPOINTZM
|| type == GAIA_MULTILINESTRINGZM || type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
geo = gaiaAllocGeomCollXYZM ();
else
geo = gaiaAllocGeomColl ();
geo->Srid = 0;
geo->endian_arch = (char) endian_arch;
geo->endian = (char) little_endian;
geo->blob = blob;
geo->size = size;
geo->offset = 5;
switch (type)
{
case GAIA_POINT:
ParseWkbPoint (geo);
break;
case GAIA_POINTZ:
case GAIA_GEOSWKB_POINTZ:
ParseWkbPointZ (geo);
break;
case GAIA_POINTM:
ParseWkbPointM (geo);
break;
case GAIA_POINTZM:
ParseWkbPointZM (geo);
break;
case GAIA_LINESTRING:
ParseWkbLine (geo);
break;
case GAIA_LINESTRINGZ:
case GAIA_GEOSWKB_LINESTRINGZ:
ParseWkbLineZ (geo);
break;
case GAIA_LINESTRINGM:
ParseWkbLineM (geo);
break;
case GAIA_LINESTRINGZM:
ParseWkbLineZM (geo);
break;
case GAIA_POLYGON:
ParseWkbPolygon (geo);
break;
case GAIA_POLYGONZ:
case GAIA_GEOSWKB_POLYGONZ:
ParseWkbPolygonZ (geo);
break;
case GAIA_POLYGONM:
ParseWkbPolygonM (geo);
break;
case GAIA_POLYGONZM:
ParseWkbPolygonZM (geo);
break;
case GAIA_MULTIPOINT:
case GAIA_MULTILINESTRING:
case GAIA_MULTIPOLYGON:
case GAIA_GEOMETRYCOLLECTION:
case GAIA_MULTIPOINTZ:
case GAIA_MULTILINESTRINGZ:
case GAIA_MULTIPOLYGONZ:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_GEOSWKB_MULTIPOINTZ:
case GAIA_GEOSWKB_MULTILINESTRINGZ:
case GAIA_GEOSWKB_MULTIPOLYGONZ:
case GAIA_GEOSWKB_GEOMETRYCOLLECTIONZ:
case GAIA_MULTIPOINTM:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTIPOLYGONM:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_MULTIPOINTZM:
case GAIA_MULTILINESTRINGZM:
case GAIA_MULTIPOLYGONZM:
case GAIA_GEOMETRYCOLLECTIONZM:
ParseWkbGeometry (geo, 1);
break;
default:
break;
};
gaiaMbrGeometry (geo);
switch (type)
{
case GAIA_POINT:
case GAIA_POINTZ:
case GAIA_GEOSWKB_POINTZ:
case GAIA_POINTM:
case GAIA_POINTZM:
geo->DeclaredType = GAIA_POINT;
break;
case GAIA_LINESTRING:
case GAIA_LINESTRINGZ:
case GAIA_GEOSWKB_LINESTRINGZ:
case GAIA_LINESTRINGM:
case GAIA_LINESTRINGZM:
geo->DeclaredType = GAIA_LINESTRING;
break;
case GAIA_POLYGON:
case GAIA_POLYGONZ:
case GAIA_GEOSWKB_POLYGONZ:
case GAIA_POLYGONM:
case GAIA_POLYGONZM:
geo->DeclaredType = GAIA_POLYGON;
break;
case GAIA_MULTIPOINT:
case GAIA_MULTIPOINTZ:
case GAIA_GEOSWKB_MULTIPOINTZ:
case GAIA_MULTIPOINTM:
case GAIA_MULTIPOINTZM:
geo->DeclaredType = GAIA_MULTIPOINT;
break;
case GAIA_MULTILINESTRING:
case GAIA_MULTILINESTRINGZ:
case GAIA_GEOSWKB_MULTILINESTRINGZ:
case GAIA_MULTILINESTRINGM:
case GAIA_MULTILINESTRINGZM:
geo->DeclaredType = GAIA_MULTILINESTRING;
break;
case GAIA_MULTIPOLYGON:
case GAIA_MULTIPOLYGONZ:
case GAIA_GEOSWKB_MULTIPOLYGONZ:
case GAIA_MULTIPOLYGONM:
case GAIA_MULTIPOLYGONZM:
geo->DeclaredType = GAIA_MULTIPOLYGON;
break;
case GAIA_GEOMETRYCOLLECTION:
case GAIA_GEOMETRYCOLLECTIONZ:
case GAIA_GEOSWKB_GEOMETRYCOLLECTIONZ:
case GAIA_GEOMETRYCOLLECTIONM:
case GAIA_GEOMETRYCOLLECTIONZM:
geo->DeclaredType = GAIA_GEOMETRYCOLLECTION;
break;
}
return geo;
}
GAIAGEO_DECLARE char *
gaiaToHexWkb (gaiaGeomCollPtr geom)
{
/* builds the hexadecimal WKB representation for this GEOMETRY */
unsigned char *wkb = NULL;
int size = 0;
char *hexbuf = NULL;
int i;
char hex[16];
char *p;
gaiaToWkb (geom, &wkb, &size);
if (!wkb)
return NULL;
hexbuf = malloc ((size * 2) + 1);
p = hexbuf;
for (i = 0; i < size; i++)
{
sprintf (hex, "%02X", *(wkb + i));
*p++ = hex[0];
*p++ = hex[1];
}
*p = '\0';
return hexbuf;
}
GAIAGEO_DECLARE void
gaiaToWkb (gaiaGeomCollPtr geom, unsigned char **result, int *size)
{
/* builds the WKB representation for this GEOMETRY */
int ib;
int iv;
double x;
double y;
double z = 0.0;
double m = 0.0;
int entities = 0;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int type;
unsigned char *ptr;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
int endian_arch = gaiaEndianArch ();
gaiaMbrGeometry (geom);
/* how many entities, and of what kind, do we have ? */
pt = geom->FirstPoint;
while (pt)
{
point = pt;
entities++;
n_points++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
line = ln;
entities++;
n_linestrings++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
polyg = pg;
entities++;
n_polygons++;
pg = pg->Next;
}
*size = 0;
*result = NULL;
if (n_points == 0 && n_polygons == 0 && n_linestrings == 0)
return;
/* ok, we can determine the geometry class */
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POINTZM;
else
type = GAIA_POINT;
}
}
else if (n_points > 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOINTZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOINTM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOINTZM;
else
type = GAIA_MULTIPOINT;
}
}
else if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_LINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_LINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_LINESTRINGZM;
else
type = GAIA_LINESTRING;
}
}
else if (n_points == 0 && n_linestrings > 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTILINESTRINGZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTILINESTRINGM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTILINESTRINGZM;
else
type = GAIA_MULTILINESTRING;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_POLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_POLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_POLYGONZM;
else
type = GAIA_POLYGON;
}
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_MULTIPOLYGONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_MULTIPOLYGONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_MULTIPOLYGONZM;
else
type = GAIA_MULTIPOLYGON;
}
}
else
{
if (geom->DimensionModel == GAIA_XY_Z)
type = GAIA_GEOMETRYCOLLECTIONZ;
else if (geom->DimensionModel == GAIA_XY_M)
type = GAIA_GEOMETRYCOLLECTIONM;
else if (geom->DimensionModel == GAIA_XY_Z_M)
type = GAIA_GEOMETRYCOLLECTIONZM;
else
type = GAIA_GEOMETRYCOLLECTION;
}
/* and now we compute the size of WKB */
*size = 5; /* header size */
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_MULTIPOLYGONZM || type == GAIA_GEOMETRYCOLLECTIONZM)
*size += 4;
point = geom->FirstPoint;
while (point)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
*size += 5;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (sizeof (double) * 3); /* three doubles for each POINT */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (sizeof (double) * 4); /* four doubles for each POINT */
else
*size += (sizeof (double) * 2); /* two doubles for each POINT */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
*size += 5;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (4 + ((sizeof (double) * 3) * line->Points)); /* # points + [x,y,z] for each vertex */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + ((sizeof (double) * 4) * line->Points)); /* # points + [x,y,z,m] for each vertex */
else
*size += (4 + ((sizeof (double) * 2) * line->Points)); /* # points + [x,y] for each vertex */
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
*size += 5;
rng = polyg->Exterior;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (8 + ((sizeof (double) * 3) * rng->Points)); /* # rings + # points + [x,y,z] array - exterior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (8 + ((sizeof (double) * 4) * rng->Points)); /* # rings + # points + [x,y,z,m] array - exterior ring */
else
*size += (8 + ((sizeof (double) * 2) * rng->Points)); /* # rings + # points + [x,y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
*size += (4 + ((sizeof (double) * 3) * rng->Points)); /* # points + [x,y,z] array - interior ring */
else if (geom->DimensionModel == GAIA_XY_Z_M)
*size += (4 + ((sizeof (double) * 4) * rng->Points)); /* # points + [x,y,z,m] array - interior ring */
else
*size += (4 + ((sizeof (double) * 2) * rng->Points)); /* # points + [x,y] array - interior ring */
}
polyg = polyg->Next;
}
*result = malloc (*size);
ptr = *result;
/* and finally we build the WKB */
*ptr = 0x01; /* little endian byte order */
gaiaExport32 (ptr + 1, type, 1, endian_arch); /* the main CLASS TYPE */
ptr += 5;
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_MULTIPOLYGONZM || type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaExport32 (ptr, entities, 1, endian_arch); /* it's a collection; # entities */
ptr += 4;
}
point = geom->FirstPoint;
while (point)
{
if (type == GAIA_MULTIPOINT || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOINTZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOINTM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOINTZM || type == GAIA_GEOMETRYCOLLECTIONZM)
{
*ptr = 0x01;
/* it's a collection: the CLASS TYPE for this element */
if (type == GAIA_MULTIPOINTZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
gaiaExport32 (ptr + 1, GAIA_POINTZ, 1, endian_arch);
else if (type == GAIA_MULTIPOINTM
|| type == GAIA_GEOMETRYCOLLECTIONM)
gaiaExport32 (ptr + 1, GAIA_POINTM, 1, endian_arch);
else if (type == GAIA_MULTIPOINTZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
gaiaExport32 (ptr + 1, GAIA_POINTZM, 1, endian_arch);
else
gaiaExport32 (ptr + 1, GAIA_POINT, 1, endian_arch);
ptr += 5;
}
gaiaExport64 (ptr, point->X, 1, endian_arch); /* X */
gaiaExport64 (ptr + 8, point->Y, 1, endian_arch); /* Y */
ptr += 16;
if (type == GAIA_POINTZ || type == GAIA_MULTIPOINTZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaExport64 (ptr, point->Z, 1, endian_arch); /* Z */
ptr += 8;
}
if (type == GAIA_POINTM || type == GAIA_MULTIPOINTM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaExport64 (ptr, point->M, 1, endian_arch); /* M */
ptr += 8;
}
if (type == GAIA_POINTZM || type == GAIA_MULTIPOINTZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaExport64 (ptr, point->Z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 8, point->M, 1, endian_arch); /* M */
ptr += 16;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if (type == GAIA_MULTILINESTRING || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTILINESTRINGZ
|| type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTILINESTRINGM
|| type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTILINESTRINGZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
*ptr = 0x01;
/* it's a collection: the CLASS TYPE for this element */
if (type == GAIA_MULTILINESTRINGZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGZ, 1, endian_arch);
else if (type == GAIA_MULTILINESTRINGM
|| type == GAIA_GEOMETRYCOLLECTIONM)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGM, 1, endian_arch);
else if (type == GAIA_MULTILINESTRINGZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
gaiaExport32 (ptr + 1, GAIA_LINESTRINGZM, 1, endian_arch);
else
gaiaExport32 (ptr + 1, GAIA_LINESTRING, 1, endian_arch);
ptr += 5;
}
gaiaExport32 (ptr, line->Points, 1, endian_arch); /* # points */
ptr += 4;
for (iv = 0; iv < line->Points; iv++)
{
if (type == GAIA_LINESTRINGZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
}
else if (type == GAIA_LINESTRINGM
|| type == GAIA_MULTILINESTRINGM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
}
else if (type == GAIA_LINESTRINGZM
|| type == GAIA_MULTILINESTRINGZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y */
ptr += 16;
if (type == GAIA_LINESTRINGZ || type == GAIA_MULTILINESTRINGZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
ptr += 8;
}
if (type == GAIA_LINESTRINGM || type == GAIA_MULTILINESTRINGM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M */
ptr += 8;
}
if (type == GAIA_LINESTRINGZM || type == GAIA_MULTILINESTRINGZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M */
ptr += 16;
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if (type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION
|| type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ
|| type == GAIA_MULTIPOLYGONM || type == GAIA_GEOMETRYCOLLECTIONM
|| type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
*ptr = 0x01;
/* it's a collection: the CLASS TYPE for this element */
if (type == GAIA_MULTIPOLYGONZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
gaiaExport32 (ptr + 1, GAIA_POLYGONZ, 1, endian_arch);
else if (type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
gaiaExport32 (ptr + 1, GAIA_POLYGONM, 1, endian_arch);
else if (type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
gaiaExport32 (ptr + 1, GAIA_POLYGONZM, 1, endian_arch);
else
gaiaExport32 (ptr + 1, GAIA_POLYGON, 1, endian_arch);
ptr += 5;
}
gaiaExport32 (ptr, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
rng = polyg->Exterior;
gaiaExport32 (ptr + 4, rng->Points, 1, endian_arch); /* # points - exterior ring */
ptr += 8;
for (iv = 0; iv < rng->Points; iv++)
{
if (type == GAIA_POLYGONZ || type == GAIA_MULTIPOLYGONZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (type == GAIA_POLYGONM || type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (type == GAIA_POLYGONZM || type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X - exterior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - exterior ring */
ptr += 16;
if (type == GAIA_POLYGONZ || type == GAIA_MULTIPOLYGONZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z - exterior ring */
ptr += 8;
}
if (type == GAIA_POLYGONM || type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M - exterior ring */
ptr += 8;
}
if (type == GAIA_POLYGONZM || type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z - exterior ring */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M - exterior ring */
ptr += 16;
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
if (type == GAIA_POLYGONZ || type == GAIA_MULTIPOLYGONZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (type == GAIA_POLYGONM
|| type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (type == GAIA_POLYGONZM
|| type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, 1, endian_arch); /* X - interior ring */
gaiaExport64 (ptr + 8, y, 1, endian_arch); /* Y - interior ring */
ptr += 16;
if (type == GAIA_POLYGONZ || type == GAIA_MULTIPOLYGONZ
|| type == GAIA_GEOMETRYCOLLECTIONZ)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z - exterior ring */
ptr += 8;
}
if (type == GAIA_POLYGONM || type == GAIA_MULTIPOLYGONM
|| type == GAIA_GEOMETRYCOLLECTIONM)
{
gaiaExport64 (ptr, m, 1, endian_arch); /* M - exterior ring */
ptr += 8;
}
if (type == GAIA_POLYGONZM || type == GAIA_MULTIPOLYGONZM
|| type == GAIA_GEOMETRYCOLLECTIONZM)
{
gaiaExport64 (ptr, z, 1, endian_arch); /* Z - exterior ring */
gaiaExport64 (ptr + 8, m, 1, endian_arch); /* M - exterior ring */
ptr += 16;
}
}
}
polyg = polyg->Next;
}
}
GAIAGEO_DECLARE int
gaiaEwkbGetPoint (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian, int endian_arch,
int dims)
{
/* decodes a POINT from PostGIS EWKB binary GEOMETRY */
double x;
double y;
double z;
double m;
switch (dims)
{
case GAIA_XY_Z_M:
if (blob_size < offset + 32)
return -1;
break;
case GAIA_XY_Z:
case GAIA_XY_M:
if (blob_size < offset + 24)
return -1;
break;
default:
if (blob_size < offset + 16)
return -1;
break;
}
x = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
y = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
if (dims == GAIA_XY_Z_M)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
}
else if (dims == GAIA_XY_Z)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaAddPointToGeomCollXYZ (geom, x, y, z);
}
else if (dims == GAIA_XY_M)
{
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaAddPointToGeomCollXYM (geom, x, y, m);
}
else
gaiaAddPointToGeomColl (geom, x, y);
return offset;
}
GAIAGEO_DECLARE int
gaiaEwkbGetLinestring (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims)
{
/* decodes a LINESTRING from PostGIS binary GEOMETRY */
int npoints;
int iv;
double x;
double y;
double z;
double m;
gaiaLinestringPtr ln;
if (blob_size < offset + 4)
return -1;
npoints = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
switch (dims)
{
case GAIA_XY_Z_M:
if (blob_size < offset + (32 * npoints))
return -1;
break;
case GAIA_XY_Z:
case GAIA_XY_M:
if (blob_size < offset + (24 * npoints))
return -1;
break;
default:
if (blob_size < offset + (16 * npoints))
return -1;
break;
}
ln = gaiaAddLinestringToGeomColl (geom, npoints);
for (iv = 0; iv < npoints; iv++)
{
x = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
y = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
if (dims == GAIA_XY_Z_M)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYZM (ln->Coords, iv, x, y, z, m);
}
else if (dims == GAIA_XY_Z)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
}
else if (dims == GAIA_XY_M)
{
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYM (ln->Coords, iv, x, y, m);
}
else
gaiaSetPoint (ln->Coords, iv, x, y);
}
return offset;
}
GAIAGEO_DECLARE int
gaiaEwkbGetPolygon (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims)
{
/* decodes a POLYGON from PostGIS binary GEOMETRY */
int rings;
int npoints;
int iv;
int ib;
double x;
double y;
double z;
double m;
gaiaPolygonPtr polyg = NULL;
gaiaRingPtr rng;
if (blob_size < offset + 4)
return -1;
rings = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ib = 0; ib < rings; ib++)
{
if (blob_size < offset + 4)
return -1;
npoints = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
switch (dims)
{
case GAIA_XY_Z_M:
if (blob_size < offset + (32 * npoints))
return -1;
break;
case GAIA_XY_Z:
case GAIA_XY_M:
if (blob_size < offset + (24 * npoints))
return -1;
break;
default:
if (blob_size < offset + (16 * npoints))
return -1;
break;
}
if (ib == 0)
{
polyg = gaiaAddPolygonToGeomColl (geom, npoints, rings - 1);
rng = polyg->Exterior;
}
else
rng = gaiaAddInteriorRing (polyg, ib - 1, npoints);
for (iv = 0; iv < npoints; iv++)
{
x = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
y = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
if (dims == GAIA_XY_Z_M)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
}
else if (dims == GAIA_XY_Z)
{
z = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
else if (dims == GAIA_XY_M)
{
m = gaiaImport64 (blob + offset, endian, endian_arch);
offset += 8;
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
else
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
return offset;
}
GAIAGEO_DECLARE int
gaiaEwkbGetMultiGeometry (gaiaGeomCollPtr geom, unsigned char *blob,
int offset, int blob_size, int endian,
int endian_arch, int dims)
{
/* decodes a MultiGeometry from PostGIS EWKB binary GEOMETRY */
int entities;
int type;
unsigned char xtype[4];
int ie;
int off;
if (blob_size < offset + 4)
return -1;
entities = gaiaImport32 (blob + offset, endian, endian_arch);
offset += 4;
for (ie = 0; ie < entities; ie++)
{
if (blob_size < offset + 5)
return -1;
memcpy (xtype, blob + offset + 1, 4);
if (endian)
xtype[3] = 0x00;
else
xtype[0] = 0x00;
type = gaiaImport32 (xtype, endian, endian_arch);
offset += 5;
switch (type)
{
case GAIA_POINT:
off =
gaiaEwkbGetPoint (geom, blob, offset, blob_size, endian,
endian_arch, dims);
if (off < 0)
return -1;
offset = off;
break;
case GAIA_LINESTRING:
off =
gaiaEwkbGetLinestring (geom, blob, offset, blob_size,
endian, endian_arch, dims);
if (off < 0)
return -1;
offset = off;
break;
case GAIA_POLYGON:
off =
gaiaEwkbGetPolygon (geom, blob, offset, blob_size, endian,
endian_arch, dims);
if (off < 0)
return -1;
offset = off;
break;
default: /* unexpected: invalid EWKB */
return -1;
};
}
return offset;
}
static int
parseHexEwkbByte (const unsigned char high, const unsigned char low,
unsigned char *byte)
{
/* parsing an Hexadecimal byte */
unsigned char hex;
switch (high)
{
case '0':
hex = 16 * 0;
break;
case '1':
hex = 16 * 1;
break;
case '2':
hex = 16 * 2;
break;
case '3':
hex = 16 * 3;
break;
case '4':
hex = 16 * 4;
break;
case '5':
hex = 16 * 5;
break;
case '6':
hex = 16 * 6;
break;
case '7':
hex = 16 * 7;
break;
case '8':
hex = 16 * 8;
break;
case '9':
hex = 16 * 9;
break;
case 'A':
case 'a':
hex = 16 * 10;
break;
case 'B':
case 'b':
hex = 16 * 11;
break;
case 'C':
case 'c':
hex = 16 * 12;
break;
case 'D':
case 'd':
hex = 16 * 13;
break;
case 'E':
case 'e':
hex = 16 * 14;
break;
case 'F':
case 'f':
hex = 16 * 15;
break;
default:
return 0;
};
switch (low)
{
case '0':
hex += 0;
break;
case '1':
hex += 1;
break;
case '2':
hex += 2;
break;
case '3':
hex += 3;
break;
case '4':
hex += 4;
break;
case '5':
hex += 5;
break;
case '6':
hex += 6;
break;
case '7':
hex += 7;
break;
case '8':
hex += 8;
break;
case '9':
hex += 9;
break;
case 'A':
case 'a':
hex += 10;
break;
case 'B':
case 'b':
hex += 11;
break;
case 'C':
case 'c':
hex += 12;
break;
case 'D':
case 'd':
hex += 13;
break;
case 'E':
case 'e':
hex += 14;
break;
case 'F':
case 'f':
hex += 15;
break;
default:
return 0;
};
*byte = hex;
return 1;
}
GAIAGEO_DECLARE unsigned char *
gaiaParseHexEWKB (const unsigned char *blob_hex, int *blob_size)
{
/* parsing an Hexadecimal EWKB Geometry */
unsigned char *blob;
unsigned char *p_out;
const unsigned char *p_in;
char high;
char low;
unsigned char hex;
int size;
int len = strlen ((const char *) blob_hex);
size = len / 2;
if (size * 2 != len)
return NULL;
blob = malloc (size);
if (!blob)
return NULL;
*blob_size = size;
p_in = blob_hex;
p_out = blob;
while (*p_in != '\0')
{
high = *p_in++;
low = *p_in++;
if (!parseHexEwkbByte (high, low, &hex))
{
free (blob);
return NULL;
}
*p_out++ = hex;
}
*blob_size = size;
return blob;
}
gaiaGeomCollPtr
gaiaFromEWKB (const unsigned char *in_buffer)
{
/* creates a Gaia own Geometry from GEOS/PostGIS EWKB */
unsigned char *blob;
int blob_size;
unsigned char xtype[4];
unsigned char xdims;
int type;
int has_z = 0;
int has_m = 0;
int dims = GAIA_XY;
int srid;
int ret;
int endian;
int endian_arch = gaiaEndianArch ();
gaiaGeomCollPtr geom = NULL;
blob = gaiaParseHexEWKB (in_buffer, &blob_size);
if (!blob)
return NULL;
if (blob_size < 9)
{
free (blob);
return NULL;
}
if (*(blob + 0) == 0x01)
endian = 1;
else
endian = 0;
memcpy (xtype, blob + 1, 4);
if (endian)
{
xdims = xtype[3];
xtype[3] = 0x00;
}
else
{
xdims = xtype[0];
xtype[0] = 0x00;
}
type = gaiaImport32 (xtype, endian, endian_arch);
if (xdims & 0x40)
has_m = 1;
if (xdims & 0x80)
has_z = 1;
if (has_m && has_z)
{
dims = GAIA_XY_Z_M;
geom = gaiaAllocGeomCollXYZM ();
}
else if (has_m)
{
dims = GAIA_XY_M;
geom = gaiaAllocGeomCollXYM ();
}
else if (has_z)
{
dims = GAIA_XY_Z;
geom = gaiaAllocGeomCollXYZ ();
}
else
{
dims = GAIA_XY;
geom = gaiaAllocGeomColl ();
}
srid = gaiaImport32 (blob + 5, endian, endian_arch);
geom->Srid = srid;
if (geom->Srid <= 0)
geom->Srid = 0;
switch (type)
{
case GAIA_POINT:
ret =
gaiaEwkbGetPoint (geom, blob, 9, blob_size, endian, endian_arch,
dims);
break;
case GAIA_LINESTRING:
ret =
gaiaEwkbGetLinestring (geom, blob, 9, blob_size, endian,
endian_arch, dims);
break;
case GAIA_POLYGON:
ret =
gaiaEwkbGetPolygon (geom, blob, 9, blob_size, endian, endian_arch,
dims);
break;
default:
ret =
gaiaEwkbGetMultiGeometry (geom, blob, 9, blob_size, endian,
endian_arch, dims);
break;
};
free (blob);
if (ret < 0)
{
/* invalid EWKB !!! */
gaiaFreeGeomColl (geom);
return NULL;
}
return geom;
}
GAIAGEO_DECLARE void
gaiaToEWKB (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom)
{
/* prints the GEOS/PostGIS EWKB text representation of current geometry */
char buf[2048];
unsigned char endian_buf[16];
char byte[3];
char *ptr;
int size;
int type;
int entities = 0;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int i;
int iv;
int ib;
double x;
double y;
double z;
double m;
int endian_arch = gaiaEndianArch ();
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
/* precomputing the required size */
size = 5; /* SRID and terminating '\0' */
pt = geom->FirstPoint;
while (pt)
{
point = pt;
entities++;
n_points++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
line = ln;
entities++;
n_linestrings++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
polyg = pg;
entities++;
n_polygons++;
pg = pg->Next;
}
if (n_points == 0 && n_polygons == 0 && n_linestrings == 0)
return;
/* ok, we can determine the geometry class */
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
type = GAIA_MULTIPOINT;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POINT;
}
else if (n_points > 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOINT;
}
else if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
type = GAIA_MULTILINESTRING;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_LINESTRING;
}
else if (n_points == 0 && n_linestrings > 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTILINESTRING;
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
type = GAIA_MULTIPOLYGON;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POLYGON;
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOLYGON;
}
else
type = GAIA_GEOMETRYCOLLECTION;
/* and now we compute the size of EWKB */
size += 10; /* header size */
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
size += 8;
point = geom->FirstPoint;
while (point)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
size += 10;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
size += 48; /* three doubles for each POINT */
else if (geom->DimensionModel == GAIA_XY_Z_M)
size += 64; /* four doubles for each POINT */
else
size += 32; /* two doubles for each POINT */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
size += 10;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
size += 8 + (line->Points * 48); /* three doubles for each VERTEX */
else if (geom->DimensionModel == GAIA_XY_Z_M)
size += 8 + (line->Points * 64); /* four doubles for each VERTEX */
else
size += 8 + (line->Points * 32); /* two doubles for each VERTEX */
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
size += 10;
rng = polyg->Exterior;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
size += 16 + (rng->Points * 48); /* three doubles for each VERTEX */
else if (geom->DimensionModel == GAIA_XY_Z_M)
size += 16 + (rng->Points * 64); /* four doubles for each VERTEX */
else
size += 16 + (rng->Points * 32); /* two doubles for each VERTEX */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
if (geom->DimensionModel == GAIA_XY_Z
|| geom->DimensionModel == GAIA_XY_M)
size += 8 + (rng->Points * 48); /* three doubles for each VERTEX */
else if (geom->DimensionModel == GAIA_XY_Z_M)
size += 8 + (rng->Points * 64); /* four doubles for each VERTEX */
else
size += 8 + (rng->Points * 32); /* two doubles for each VERTEX */
}
polyg = polyg->Next;
}
/* and finally we build the EWKB expression */
ptr = buf;
*ptr++ = '0'; /* little endian byte order */
*ptr++ = '1';
gaiaExport32 (endian_buf, type, 1, endian_arch); /* the main CLASS TYPE */
for (i = 0; i < 3; i++)
{
/* CAVEAT: the 4th byte in PostGIS encodes M/Z presence !!!! */
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
/* marking dimensions and M/Z presence */
if (geom->DimensionModel == GAIA_XY_Z)
{
*ptr++ = 'A';
*ptr++ = '0';
}
else if (geom->DimensionModel == GAIA_XY_M)
{
*ptr++ = '6';
*ptr++ = '0';
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
*ptr++ = 'E';
*ptr++ = '0';
}
else
{
*ptr++ = '2';
*ptr++ = '0';
}
gaiaExport32 (endian_buf, geom->Srid, 1, endian_arch);
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
{
gaiaExport32 (endian_buf, entities, 1, endian_arch); /* it's a collection; # entities */
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
point = geom->FirstPoint;
while (point)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
if (type == GAIA_MULTIPOINT || type == GAIA_GEOMETRYCOLLECTION)
{
*ptr++ = '0';
*ptr++ = '1';
/* it's a collection: the CLASS TYPE for this element */
gaiaExport32 (endian_buf, GAIA_POINT, 1, endian_arch);
for (i = 0; i < 3; i++)
{
/* CAVEAT: the 4th byte in PostGIS encodes M/Z presence !!!! */
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
/* marking M/Z presence */
if (geom->DimensionModel == GAIA_XY_Z)
*ptr++ = '8';
else if (geom->DimensionModel == GAIA_XY_M)
*ptr++ = '4';
else if (geom->DimensionModel == GAIA_XY_Z_M)
*ptr++ = 'C';
else
*ptr++ = '0';
*ptr++ = '0';
}
gaiaExport64 (endian_buf, point->X, 1, endian_arch); /* X */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, point->Y, 1, endian_arch); /* Y */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (endian_buf, point->Z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (endian_buf, point->M, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (endian_buf, point->Z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, point->M, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
if (type == GAIA_MULTILINESTRING || type == GAIA_GEOMETRYCOLLECTION)
{
*ptr++ = '0';
*ptr++ = '1';
/* it's a collection: the CLASS TYPE for this element */
gaiaExport32 (endian_buf, GAIA_LINESTRING, 1, endian_arch);
for (i = 0; i < 3; i++)
{
/* CAVEAT: the 4th byte in PostGIS encodes M/Z presence !!!! */
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
/* marking M/Z presence */
if (geom->DimensionModel == GAIA_XY_Z)
*ptr++ = '8';
else if (geom->DimensionModel == GAIA_XY_M)
*ptr++ = '4';
else if (geom->DimensionModel == GAIA_XY_Z_M)
*ptr++ = 'C';
else
*ptr++ = '0';
*ptr++ = '0';
}
gaiaExport32 (endian_buf, line->Points, 1, endian_arch); /* # points */
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
for (iv = 0; iv < line->Points; iv++)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
gaiaLineGetPoint (line, iv, &x, &y, &z, &m);
gaiaExport64 (endian_buf, x, 1, endian_arch); /* X */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, y, 1, endian_arch); /* Y */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
if (type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
{
*ptr++ = '0';
*ptr++ = '1';
/* it's a collection: the CLASS TYPE for this element */
gaiaExport32 (endian_buf, GAIA_POLYGON, 1, endian_arch);
for (i = 0; i < 3; i++)
{
/* CAVEAT: the 4th byte in PostGIS encodes M/Z presence !!!! */
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
/* marking M/Z presence */
if (geom->DimensionModel == GAIA_XY_Z)
*ptr++ = '8';
else if (geom->DimensionModel == GAIA_XY_M)
*ptr++ = '4';
else if (geom->DimensionModel == GAIA_XY_Z_M)
*ptr++ = 'C';
else
*ptr++ = '0';
*ptr++ = '0';
}
gaiaExport32 (endian_buf, polyg->NumInteriors + 1, 1, endian_arch); /* # rings */
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
rng = polyg->Exterior;
gaiaExport32 (endian_buf, rng->Points, 1, endian_arch); /* # points - exterior ring */
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
for (iv = 0; iv < rng->Points; iv++)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
gaiaRingGetPoint (rng, iv, &x, &y, &z, &m);
gaiaExport64 (endian_buf, x, 1, endian_arch); /* X - exterior ring */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, y, 1, endian_arch); /* Y - exterior ring */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (endian_buf, rng->Points, 1, endian_arch); /* # points - interior ring */
for (i = 0; i < 4; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
for (iv = 0; iv < rng->Points; iv++)
{
if ((ptr - buf) > 1024)
{
/* flushing the internal buffer */
*ptr++ = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
ptr = buf;
}
gaiaRingGetPoint (rng, iv, &x, &y, &z, &m);
gaiaExport64 (endian_buf, x, 1, endian_arch); /* X - interior ring */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, y, 1, endian_arch); /* Y - interior ring */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaExport64 (endian_buf, z, 1, endian_arch); /* Z */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
gaiaExport64 (endian_buf, m, 1, endian_arch); /* M */
for (i = 0; i < 8; i++)
{
sprintf (byte, "%02X", endian_buf[i]);
*ptr++ = byte[0];
*ptr++ = byte[1];
}
}
}
}
polyg = polyg->Next;
}
/* terminating the EWKB string */
*ptr = '\0';
gaiaAppendToOutBuffer (out_buf, buf);
}
static int
coordDimsFromFgf (int endian_arch, const unsigned char *blob, unsigned int size,
int *type)
{
/* decoding the coordinate Dimensions for an FGF Geometry */
int coord_dims;
if (size < 4)
return 0;
coord_dims = gaiaImport32 (blob, GAIA_LITTLE_ENDIAN, endian_arch);
*type = coord_dims;
switch (coord_dims)
{
case GAIA_XY:
return 2;
case GAIA_XY_M:
case GAIA_XY_Z:
return 3;
case GAIA_XY_Z_M:
return 4;
default:
return 0;
}
}
static int
pointFromFgf (gaiaGeomCollPtr geom, int endian_arch, const unsigned char *blob,
unsigned int size, unsigned int *consumed)
{
/* decoding a POINT Geometry from FGF */
double x;
double y;
double z;
double m;
unsigned int sz = size;
const unsigned char *ptr = blob;
int coord_dims;
int type;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_POINT)
return 0;
ptr += 4;
sz -= 4;
/* checking size */
if (sz < 4)
return 0;
coord_dims = coordDimsFromFgf (endian_arch, ptr, size, &type);
if (!coord_dims)
return 0;
ptr += 4;
sz -= 4;
if (sz < (coord_dims * sizeof (double)))
return 0;
if (consumed)
*consumed = coord_dims * sizeof (double);
if (type == GAIA_XY_Z)
{
/* building the POINTZ */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaAddPointToGeomCollXYZ (geom, x, y, z);
}
else if (type == GAIA_XY_M)
{
/* building the POINTM */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaAddPointToGeomCollXYM (geom, x, y, m);
}
else if (type == GAIA_XY_Z_M)
{
/* building the POINTZM */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaAddPointToGeomCollXYZM (geom, x, y, z, m);
}
else
{
/* building the POINT */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + 8, GAIA_LITTLE_ENDIAN, endian_arch);
gaiaAddPointToGeomColl (geom, x, y);
}
return 1;
}
static int
linestringFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size,
unsigned int *consumed)
{
/* decoding a LINESTRING Geometry from FGF */
gaiaLinestringPtr ln;
int pts;
int iv;
double x;
double y;
unsigned int ln_sz;
unsigned int sz = size;
const unsigned char *ptr = blob;
int coord_dims;
int type;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_LINESTRING)
return 0;
ptr += 4;
sz -= 4;
/* checking size */
coord_dims = coordDimsFromFgf (endian_arch, ptr, size, &type);
if (!coord_dims)
return 0;
ptr += 4;
sz -= 4;
/* how many points are there ? */
if (sz < 4)
return 0;
pts = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
if (pts < 2)
return 0;
ln_sz = pts * coord_dims * sizeof (double);
if (sz < ln_sz)
return 0;
if (consumed)
*consumed = (12 + ln_sz);
if (type == GAIA_XY_Z)
{
/* building the LINESTRINGZ */
geom->DimensionModel = GAIA_XY_Z;
ln = gaiaAddLinestringToGeomColl (geom, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the linestring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + sizeof (double), GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
else if (type == GAIA_XY_M)
{
/* building the LINESTRINGM */
geom->DimensionModel = GAIA_XY_M;
ln = gaiaAddLinestringToGeomColl (geom, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the linestring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + sizeof (double), GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
else if (type == GAIA_XY_Z_M)
{
/* building the LINESTRINGZM */
geom->DimensionModel = GAIA_XY_Z_M;
ln = gaiaAddLinestringToGeomColl (geom, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the linestring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + sizeof (double), GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
else
{
/* building the LINESTRING */
geom->DimensionModel = GAIA_XY;
ln = gaiaAddLinestringToGeomColl (geom, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the linestring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
y = gaiaImport64 (ptr + sizeof (double), GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (ln->Coords, iv, x, y);
}
}
return 1;
}
static int
polygonFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size,
unsigned int *consumed)
{
/* decoding a POLYGON Geometry from FGF */
gaiaPolygonPtr pg = NULL;
gaiaRingPtr rng;
int rings;
int ir;
int pts;
int iv;
double x;
double y;
double z;
double m;
unsigned int rng_sz;
unsigned int sz = size;
const unsigned char *ptr = blob;
int coord_dims;
int type;
unsigned int bytes = 0;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_POLYGON)
return 0;
ptr += 4;
sz -= 4;
bytes += 4;
/* checking size */
coord_dims = coordDimsFromFgf (endian_arch, ptr, size, &type);
if (!coord_dims)
return 0;
ptr += 4;
sz -= 4;
bytes += 4;
/* how many rings are there ? */
if (sz < 4)
return 0;
rings = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
bytes += 4;
if (rings < 1)
return 0;
for (ir = 0; ir < rings; ir++)
{
/* fetching Polygon's rings */
if (sz < 4)
return 0;
pts = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
bytes += 4;
if (pts < 4)
return 0;
rng_sz = pts * coord_dims * sizeof (double);
if (sz < rng_sz)
return 0;
bytes += rng_sz;
if (type == GAIA_XY_Z)
{
/* POLYGONZ */
geom->DimensionModel = GAIA_XY_Z;
if (ir == 0)
{
/* building the EXTERIOR RING */
pg = gaiaAddPolygonToGeomColl (geom, pts, rings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the EXTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
}
else
{
/* building an INTERIOR RING */
rng = gaiaAddInteriorRing (pg, ir - 1, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into some INTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
}
}
}
if (type == GAIA_XY_M)
{
/* POLYGONM */
geom->DimensionModel = GAIA_XY_M;
if (ir == 0)
{
/* building the EXTERIOR RING */
pg = gaiaAddPolygonToGeomColl (geom, pts, rings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the EXTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
}
else
{
/* building an INTERIOR RING */
rng = gaiaAddInteriorRing (pg, ir - 1, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into some INTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYM (rng->Coords, iv, x, y, m);
}
}
}
else if (type == GAIA_XY_Z_M)
{
/* POLYGONZM */
geom->DimensionModel = GAIA_XY_Z_M;
if (ir == 0)
{
/* building the EXTERIOR RING */
pg = gaiaAddPolygonToGeomColl (geom, pts, rings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the EXTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + (sizeof (double) * 3),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
}
}
else
{
/* building an INTERIOR RING */
rng = gaiaAddInteriorRing (pg, ir - 1, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into some INTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
z = gaiaImport64 (ptr + (sizeof (double) * 2),
GAIA_LITTLE_ENDIAN, endian_arch);
m = gaiaImport64 (ptr + (sizeof (double) * 3),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPointXYZM (rng->Coords, iv, x, y, z, m);
}
}
}
else
{
/* POLYGON */
geom->DimensionModel = GAIA_XY;
if (ir == 0)
{
/* building the EXTERIOR RING */
pg = gaiaAddPolygonToGeomColl (geom, pts, rings - 1);
rng = pg->Exterior;
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into the EXTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
else
{
/* building an INTERIOR RING */
rng = gaiaAddInteriorRing (pg, ir - 1, pts);
for (iv = 0; iv < pts; iv++)
{
/* inserting vertices into some INTERIOR Ring */
x = gaiaImport64 (ptr, GAIA_LITTLE_ENDIAN,
endian_arch);
y = gaiaImport64 (ptr + sizeof (double),
GAIA_LITTLE_ENDIAN, endian_arch);
ptr += (coord_dims * sizeof (double));
gaiaSetPoint (rng->Coords, iv, x, y);
}
}
}
sz -= rng_sz;
}
if (consumed)
*consumed = bytes;
return 1;
}
static int
multiPointFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size)
{
/* decoding a MULTIPOINT Geometry from FGF */
int pts;
int ipt;
unsigned int sz = size;
const unsigned char *ptr = blob;
unsigned int consumed;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_MULTIPOINT)
return 0;
ptr += 4;
sz -= 4;
/* how many points are there ? */
if (sz < 4)
return 0;
pts = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
if (pts < 1)
return 0;
for (ipt = 0; ipt < pts; ipt++)
{
/* fetching individual Points from FGF */
if (!pointFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
ptr += consumed;
sz -= consumed;
}
return 1;
}
static int
multiLinestringFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size)
{
/* decoding a MULTILINESTRING Geometry from FGF */
int lns;
int iln;
unsigned int sz = size;
const unsigned char *ptr = blob;
unsigned int consumed;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32
(ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_MULTILINESTRING)
return 0;
ptr += 4;
sz -= 4;
/* how many linestrings are there ? */
if (sz < 4)
return 0;
lns = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
if (lns < 1)
return 0;
for (iln = 0; iln < lns; iln++)
{
/* fetching individual Linestrings from FGF */
if (!linestringFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
ptr += consumed;
sz -= consumed;
}
return 1;
}
static int
multiPolygonFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size)
{
/* decoding a MULTIPOLYGON Geometry from FGF */
int pgs;
int ipg;
unsigned int sz = size;
const unsigned char *ptr = blob;
unsigned int consumed;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32
(ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_MULTIPOLYGON)
return 0;
ptr += 4;
sz -= 4;
/* how many polygons are there ? */
if (sz < 4)
return 0;
pgs = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
if (pgs < 1)
return 0;
for (ipg = 0; ipg < pgs; ipg++)
{
/* fetching individual Polygons from FGF */
if (!polygonFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
ptr += consumed;
sz -= consumed;
}
return 1;
}
static int
geomCollectionFromFgf (gaiaGeomCollPtr geom, int endian_arch,
const unsigned char *blob, unsigned int size)
{
/* decoding a GEOMETRYCOLLECTION Geometry from FGF */
int geoms;
int ig;
int geom_type;
unsigned int sz = size;
const unsigned char *ptr = blob;
unsigned int consumed;
/* checking Geometry Type */
if (sz < 4)
return 0;
if (gaiaImport32
(ptr, GAIA_LITTLE_ENDIAN, endian_arch) != GAIA_GEOMETRYCOLLECTION)
return 0;
ptr += 4;
sz -= 4;
/* how many individual Geometries are there ? */
if (sz < 4)
return 0;
geoms = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 4;
sz -= 4;
if (geoms < 1)
return 0;
for (ig = 0; ig < geoms; ig++)
{
/* fetching individual Geometries from FGF */
if (sz < 4)
return 0;
geom_type = gaiaImport32 (ptr, GAIA_LITTLE_ENDIAN, endian_arch);
switch (geom_type)
{
case GAIA_POINT:
if (!pointFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
break;
case GAIA_LINESTRING:
if (!linestringFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
break;
case GAIA_POLYGON:
if (!polygonFromFgf (geom, endian_arch, ptr, sz, &consumed))
return 0;
break;
default: /* unsupported geometry type */
return 0;
break;
};
ptr += consumed;
sz -= consumed;
}
return 1;
}
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromFgf (const unsigned char *blob, unsigned int size)
{
/* decoding from FGF to GEOMETRY */
gaiaGeomCollPtr geom = NULL;
int geom_type;
int endian_arch = gaiaEndianArch ();
if (size < 4)
return NULL;
/* checking FGF type */
geom_type = gaiaImport32 (blob, GAIA_LITTLE_ENDIAN, endian_arch);
geom = gaiaAllocGeomColl ();
geom->DeclaredType = geom_type;
switch (geom_type)
{
case GAIA_POINT:
if (pointFromFgf (geom, endian_arch, blob, size, NULL))
return geom;
break;
case GAIA_LINESTRING:
if (linestringFromFgf (geom, endian_arch, blob, size, NULL))
return geom;
break;
case GAIA_POLYGON:
if (polygonFromFgf (geom, endian_arch, blob, size, NULL))
return geom;
break;
case GAIA_MULTIPOINT:
if (multiPointFromFgf (geom, endian_arch, blob, size))
return geom;
break;
case GAIA_MULTILINESTRING:
if (multiLinestringFromFgf (geom, endian_arch, blob, size))
return geom;
break;
case GAIA_MULTIPOLYGON:
if (multiPolygonFromFgf (geom, endian_arch, blob, size))
return geom;
break;
case GAIA_GEOMETRYCOLLECTION:
if (geomCollectionFromFgf (geom, endian_arch, blob, size))
return geom;
break;
default: /* unsupported geometry type */
break;
};
gaiaFreeGeomColl (geom);
return NULL;
}
GAIAGEO_DECLARE void
gaiaToFgf (gaiaGeomCollPtr geom, unsigned char **result, int *size,
int coord_dims)
{
/* builds the FGF representation for this GEOMETRY */
int ib;
int iv;
double x;
double y;
double z;
double m;
int entities = 0;
int n_points = 0;
int n_linestrings = 0;
int n_polygons = 0;
int type;
int n_coords;
unsigned char *ptr;
int sz = 0;
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
gaiaPointPtr point = NULL;
gaiaLinestringPtr line = NULL;
gaiaPolygonPtr polyg = NULL;
int endian_arch = gaiaEndianArch ();
gaiaMbrGeometry (geom);
switch (coord_dims)
{
case GAIA_XY:
n_coords = 2;
break;
case GAIA_XY_M:
case GAIA_XY_Z:
n_coords = 3;
break;
case GAIA_XY_Z_M:
n_coords = 4;
break;
default:
n_coords = 0;
break;
}
/* how many entities, and of what kind, do we have ? */
pt = geom->FirstPoint;
while (pt)
{
point = pt;
entities++;
n_points++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
line = ln;
entities++;
n_linestrings++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
polyg = pg;
entities++;
n_polygons++;
pg = pg->Next;
}
*size = 0;
sz = 0;
*result = NULL;
if (n_points == 0 && n_polygons == 0 && n_linestrings == 0)
return;
/* ok, we can determine the geometry class */
if (n_points == 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTIPOINT)
type = GAIA_MULTIPOINT;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POINT;
}
else if (n_points > 1 && n_linestrings == 0 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOINT;
}
else if (n_points == 0 && n_linestrings == 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_MULTILINESTRING)
type = GAIA_MULTILINESTRING;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_LINESTRING;
}
else if (n_points == 0 && n_linestrings > 1 && n_polygons == 0)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTILINESTRING;
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOLYGON)
type = GAIA_MULTIPOLYGON;
else if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_POLYGON;
}
else if (n_points == 0 && n_linestrings == 0 && n_polygons > 1)
{
if (geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
type = GAIA_GEOMETRYCOLLECTION;
else
type = GAIA_MULTIPOLYGON;
}
else
type = GAIA_GEOMETRYCOLLECTION;
/* and now we compute the size of FGF */
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
sz += 8;
point = geom->FirstPoint;
while (point)
{
sz += (8 + (n_coords * sizeof (double))); /* the size of each POINT */
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
sz += (12 + ((n_coords * sizeof (double)) * line->Points)); /* # points + [x,y] for each vertex */
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
rng = polyg->Exterior;
sz += (16 + ((n_coords * sizeof (double)) * rng->Points)); /* # rings + # points + [x.y] array - exterior ring */
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
sz += (4 + ((n_coords * sizeof (double)) * rng->Points)); /* # points + [x,y] array - interior ring */
}
polyg = polyg->Next;
}
*size = sz;
ptr = malloc (sz);
*result = ptr;
/* and finally we build the FGF */
if (type == GAIA_MULTIPOINT || type == GAIA_MULTILINESTRING
|| type == GAIA_MULTIPOLYGON || type == GAIA_GEOMETRYCOLLECTION)
{
gaiaExport32 (ptr, type, GAIA_LITTLE_ENDIAN, endian_arch); /* Geometry Type */
ptr += 4;
gaiaExport32 (ptr, entities, GAIA_LITTLE_ENDIAN, endian_arch); /* it's a collection; # entities */
ptr += 4;
}
point = geom->FirstPoint;
while (point)
{
gaiaExport32 (ptr, GAIA_POINT, GAIA_LITTLE_ENDIAN, endian_arch); /* the CLASS TYPE for this element */
ptr += 4;
gaiaExport32 (ptr, coord_dims, GAIA_LITTLE_ENDIAN, endian_arch); /* the CoordDimension */
ptr += 4;
gaiaExport64 (ptr, point->X, GAIA_LITTLE_ENDIAN, endian_arch); /* X */
ptr += 8;
gaiaExport64 (ptr, point->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* Y */
ptr += 8;
if (n_coords > 2)
{
/* the third coordinate [Z or M] */
if (coord_dims == GAIA_XY_Z || coord_dims == GAIA_XY_Z_M)
gaiaExport64 (ptr, point->Z, GAIA_LITTLE_ENDIAN,
endian_arch);
else
gaiaExport64 (ptr, point->M, GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += 8;
}
if (n_coords > 3)
{
/* the fourth coordinate [M] */
gaiaExport64 (ptr, point->M, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 8;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
gaiaExport32 (ptr, GAIA_LINESTRING, GAIA_LITTLE_ENDIAN, endian_arch); /* the CLASS TYPE for this element */
ptr += 4;
gaiaExport32 (ptr, coord_dims, GAIA_LITTLE_ENDIAN, endian_arch); /* the CoordDimension */
ptr += 4;
gaiaExport32 (ptr, line->Points, GAIA_LITTLE_ENDIAN, endian_arch); /* # points */
ptr += 4;
for (iv = 0; iv < line->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, GAIA_LITTLE_ENDIAN, endian_arch); /* X */
ptr += 8;
gaiaExport64 (ptr, y, GAIA_LITTLE_ENDIAN, endian_arch); /* Y */
ptr += 8;
if (n_coords > 2)
{
/* the third coordinate [Z or M] */
if (coord_dims == GAIA_XY_Z || coord_dims == GAIA_XY_Z_M)
gaiaExport64 (ptr, z, GAIA_LITTLE_ENDIAN,
endian_arch);
else
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += 8;
}
if (n_coords > 3)
{
/* the fourth coordinate [M]; */
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 8;
}
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
gaiaExport32 (ptr, GAIA_POLYGON, GAIA_LITTLE_ENDIAN, endian_arch); /* the CLASS TYPE for this element */
ptr += 4;
gaiaExport32 (ptr, coord_dims, GAIA_LITTLE_ENDIAN, endian_arch); /* the CoordDimension */
ptr += 4;
gaiaExport32 (ptr, polyg->NumInteriors + 1, GAIA_LITTLE_ENDIAN, endian_arch); /* # rings */
ptr += 4;
rng = polyg->Exterior;
gaiaExport32 (ptr, rng->Points, GAIA_LITTLE_ENDIAN, endian_arch); /* # points - exterior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, GAIA_LITTLE_ENDIAN, endian_arch); /* X - exterior ring */
ptr += 8;
gaiaExport64 (ptr, y, GAIA_LITTLE_ENDIAN, endian_arch); /* Y - exterior ring */
ptr += 8;
if (n_coords > 2)
{
/* the third coordinate [Z or M] */
if (coord_dims == GAIA_XY_Z || coord_dims == GAIA_XY_Z_M)
gaiaExport64 (ptr, z, GAIA_LITTLE_ENDIAN,
endian_arch);
else
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += 8;
}
if (n_coords > 3)
{
/* the fourth coordinate [M] */
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN, endian_arch);
ptr += 8;
}
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
rng = polyg->Interiors + ib;
gaiaExport32 (ptr, rng->Points, 1, endian_arch); /* # points - interior ring */
ptr += 4;
for (iv = 0; iv < rng->Points; iv++)
{
z = 0.0;
m = 0.0;
if (geom->DimensionModel == GAIA_XY_Z)
{
gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
}
else if (geom->DimensionModel == GAIA_XY_M)
{
gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
}
else if (geom->DimensionModel == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (rng->Coords, iv, &x, &y);
}
gaiaExport64 (ptr, x, GAIA_LITTLE_ENDIAN, endian_arch); /* X - interior ring */
ptr += 8;
gaiaExport64 (ptr, y, GAIA_LITTLE_ENDIAN, endian_arch); /* Y - interior ring */
ptr += 8;
if (n_coords > 2)
{
/* the third coordinate [Z or M]; defaulting to ZERO */
if (coord_dims == GAIA_XY_Z
|| coord_dims == GAIA_XY_Z_M)
gaiaExport64 (ptr, z, GAIA_LITTLE_ENDIAN,
endian_arch);
else
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += 8;
}
if (n_coords > 3)
{
/* the fourth coordinate [M] */
gaiaExport64 (ptr, m, GAIA_LITTLE_ENDIAN,
endian_arch);
ptr += 8;
}
}
}
polyg = polyg->Next;
}
}
libspatialite-5.1.0/src/gaiageo/gg_wkt.c 0000644 0001750 0001750 00000346140 14463127014 015107 0000000 0000000 /*
gg_wkt.c -- Gaia common support for WKT encoded geometries
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
Contributor(s):
Klaus Foerster klaus.foerster@svg.cc
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
static void
gaiaOutClean (char *buffer)
{
/* cleans unneeded trailing zeros */
int i;
/*
* sandro 2021-08-07
*
* fixing an issue reported by Jan Vaillant in the mailing list
* ensuring that trailing zeros will never be pruned from
* integer numbers
*/
int integer = 1;
for (i = 0; i < (int) strlen (buffer); i++)
{
if (buffer[i] == '.')
integer = 0;
}
if (integer)
goto final_clean;
/* end sandro 2021-08-07 */
for (i = strlen (buffer) - 1; i > 0; i--)
{
if (buffer[i] == '0')
buffer[i] = '\0';
else
break;
}
if (buffer[i] == '.')
buffer[i] = '\0';
final_clean:
if (strcmp (buffer, "-0") == 0)
{
/* avoiding to return embarassing NEGATIVE ZEROes */
strcpy (buffer, "0");
}
if (strcmp (buffer, "-1.#QNAN") == 0 || strcmp (buffer, "NaN") == 0
|| strcmp (buffer, "1.#QNAN") == 0
|| strcmp (buffer, "-1.#IND") == 0 || strcmp (buffer, "1.#IND") == 0)
{
/* on Windows a NaN could be represented in "odd" ways */
/* this is intended to restore a consistent behaviour */
strcpy (buffer, "nan");
}
}
GAIAGEO_DECLARE void
gaiaOutBufferInitialize (gaiaOutBufferPtr buf)
{
/* initializing a dynamically growing output buffer */
buf->Buffer = NULL;
buf->WriteOffset = 0;
buf->BufferSize = 0;
buf->Error = 0;
}
GAIAGEO_DECLARE void
gaiaOutBufferReset (gaiaOutBufferPtr buf)
{
/* cleaning a dynamically growing output buffer */
if (buf->Buffer)
free (buf->Buffer);
buf->Buffer = NULL;
buf->WriteOffset = 0;
buf->BufferSize = 0;
buf->Error = 0;
}
GAIAGEO_DECLARE void
gaiaAppendToOutBuffer (gaiaOutBufferPtr buf, const char *text)
{
/* appending a text string */
int len = strlen (text);
int free_size = buf->BufferSize - buf->WriteOffset;
if ((len + 1) > free_size)
{
/* we must allocate a bigger buffer */
int new_size;
char *new_buf;
if (buf->BufferSize == 0)
new_size = (len + 1) + 1024;
else if (buf->BufferSize <= 4196)
new_size = buf->BufferSize + (len + 1) + 4196;
else if (buf->BufferSize <= 65536)
new_size = buf->BufferSize + (len + 1) + 65536;
else
new_size = buf->BufferSize + (len + 1) + (1024 * 1024);
new_buf = malloc (new_size);
if (!new_buf)
{
buf->Error = 1;
return;
}
memcpy (new_buf, buf->Buffer, buf->WriteOffset);
if (buf->Buffer)
free (buf->Buffer);
buf->Buffer = new_buf;
buf->BufferSize = new_size;
}
strcpy (buf->Buffer + buf->WriteOffset, text);
buf->WriteOffset += len;
}
static void
gaiaOutPointStrict (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats a WKT POINT [Strict 2D] */
char *buf_x;
char *buf_y;
char *buf;
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutPoint (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats a WKT POINT */
char *buf_x;
char *buf_y;
char *buf;
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", point->X);
else
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", point->Y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
GAIAGEO_DECLARE void
gaiaOutPointZex (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats a WKT POINTZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", point->X);
else
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", point->Y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", point->Z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, point->Z);
gaiaOutClean (buf_z);
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
GAIAGEO_DECLARE void
gaiaOutPointZ (gaiaOutBufferPtr out_buf, gaiaPointPtr point)
{
/*
* formats a WKT POINTZ
* convenience method - default decimal precision
*/
gaiaOutPointZex (out_buf, point, -1);
}
static void
gaiaOutPointM (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats a WKT POINTM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", point->X);
else
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", point->Y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", point->M);
else
buf_m = sqlite3_mprintf ("%.*f", precision, point->M);
gaiaOutClean (buf_m);
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutPointZM (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats a WKT POINTZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", point->X);
else
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", point->Y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", point->Z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, point->Z);
gaiaOutClean (buf_z);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", point->M);
else
buf_m = sqlite3_mprintf ("%.*f", precision, point->M);
gaiaOutClean (buf_m);
buf = sqlite3_mprintf ("%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutEwktPoint (gaiaOutBufferPtr out_buf, gaiaPointPtr point)
{
/* formats an EWKT POINT */
char *buf_x;
char *buf_y;
char *buf;
buf_x = sqlite3_mprintf ("%1.15f", point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", point->Y);
gaiaOutClean (buf_y);
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
GAIAGEO_DECLARE void
gaiaOutEwktPointZ (gaiaOutBufferPtr out_buf, gaiaPointPtr point)
{
/* formats an EWKT POINTZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
buf_x = sqlite3_mprintf ("%1.15f", point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", point->Y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", point->Z);
gaiaOutClean (buf_z);
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutEwktPointM (gaiaOutBufferPtr out_buf, gaiaPointPtr point)
{
/* formats an EWKT POINTM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
buf_x = sqlite3_mprintf ("%1.15f", point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", point->Y);
gaiaOutClean (buf_y);
buf_m = sqlite3_mprintf ("%1.15f", point->M);
gaiaOutClean (buf_m);
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutEwktPointZM (gaiaOutBufferPtr out_buf, gaiaPointPtr point)
{
/* formats an EWKT POINTZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
buf_x = sqlite3_mprintf ("%1.15f", point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", point->Y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", point->Z);
gaiaOutClean (buf_z);
buf_m = sqlite3_mprintf ("%1.15f", point->M);
gaiaOutClean (buf_m);
buf = sqlite3_mprintf ("%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
gaiaOutLinestringStrict (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line,
int precision)
{
/* formats a WKT LINESTRING [Strict 2D] */
char *buf_x;
char *buf_y;
char *buf;
double x;
double y;
double z;
double m;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
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);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv > 0)
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
else
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutLinestring (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line,
int precision)
{
/* formats a WKT LINESTRING */
char *buf_x;
char *buf_y;
char *buf;
double x;
double y;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPoint (line->Coords, iv, &x, &y);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv > 0)
buf = sqlite3_mprintf (", %s %s", buf_x, buf_y);
else
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
GAIAGEO_DECLARE void
gaiaOutLinestringZex (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line,
int precision)
{
/* formats a WKT LINESTRINGZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
double x;
double y;
double z;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv > 0)
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
GAIAGEO_DECLARE void
gaiaOutLinestringZ (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line)
{
/*
* formats a WKT LINESTRINGZ
* convenience method - default decimal precision
*/
gaiaOutLinestringZex (out_buf, line, -1);
}
static void
gaiaOutLinestringM (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line,
int precision)
{
/* formats a WKT LINESTRINGM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
double x;
double y;
double m;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv > 0)
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutLinestringZM (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line,
int precision)
{
/* formats a WKT LINESTRINGZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
double x;
double y;
double z;
double m;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv > 0)
buf =
sqlite3_mprintf (", %s %s %s %s", buf_x, buf_y, buf_z, buf_m);
else
buf = sqlite3_mprintf ("%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutEwktLinestring (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line)
{
/* formats an EWKT LINESTRING */
char *buf_x;
char *buf_y;
char *buf;
double x;
double y;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPoint (line->Coords, iv, &x, &y);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
if (iv > 0)
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
else
buf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
GAIAGEO_DECLARE void
gaiaOutEwktLinestringZ (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line)
{
/* formats an EWKT LINESTRINGZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
double x;
double y;
double z;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
if (iv > 0)
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutEwktLinestringM (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line)
{
/* formats an EWKT LINESTRINGM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
double x;
double y;
double m;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv > 0)
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutEwktLinestringZM (gaiaOutBufferPtr out_buf, gaiaLinestringPtr line)
{
/* formats an EWKT LINESTRINGZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
double x;
double y;
double z;
double m;
int iv;
for (iv = 0; iv < line->Points; iv++)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv > 0)
buf =
sqlite3_mprintf (",%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
else
buf = sqlite3_mprintf ("%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
gaiaOutPolygonStrict (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg,
int precision)
{
/* formats a WKT POLYGON [Strict 2D] */
char *buf_x;
char *buf_y;
char *buf;
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
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);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf (",(%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
static void
gaiaOutPolygon (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg, int precision)
{
/* formats a WKT POLYGON */
char *buf_x;
char *buf_y;
char *buf;
int ib;
int iv;
double x;
double y;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (", %s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf (", (%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (", %s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
GAIAGEO_DECLARE void
gaiaOutPolygonZex (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg,
int precision)
{
/* formats a WKT POLYGONZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
int ib;
int iv;
double x;
double y;
double z;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s %s", buf_x, buf_y, buf_z);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s %s)", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf (", (%s %s %s", buf_x, buf_y, buf_z);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s %s)", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
GAIAGEO_DECLARE void
gaiaOutPolygonZ (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg)
{
/*
* formats a WKT POLYGONZ
* convenience method - default decimal precision
*/
gaiaOutPolygonZex (out_buf, polyg, -1);
}
static void
gaiaOutPolygonM (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg, int precision)
{
/* formats a WKT POLYGONM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
int ib;
int iv;
double x;
double y;
double m;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s %s", buf_x, buf_y, buf_m);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s %s)", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv == 0)
buf = sqlite3_mprintf (", (%s %s %s", buf_x, buf_y, buf_m);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (", %s %s %s)", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf (", %s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
static void
gaiaOutPolygonZM (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg, int precision)
{
/* formats a WKT POLYGONZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv == 0)
buf =
sqlite3_mprintf ("(%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
else if (iv == (ring->Points - 1))
buf =
sqlite3_mprintf (", %s %s %s %s)", buf_x, buf_y, buf_z,
buf_m);
else
buf =
sqlite3_mprintf (", %s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
if (precision < 0)
buf_x = sqlite3_mprintf ("%1.6f", x);
else
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
if (precision < 0)
buf_y = sqlite3_mprintf ("%1.6f", y);
else
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (precision < 0)
buf_z = sqlite3_mprintf ("%1.6f", z);
else
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (precision < 0)
buf_m = sqlite3_mprintf ("%1.6f", m);
else
buf_m = sqlite3_mprintf ("%.*f", precision, m);
gaiaOutClean (buf_m);
if (iv == 0)
buf =
sqlite3_mprintf (", (%s %s %s %s", buf_x, buf_y, buf_z,
buf_m);
else if (iv == (ring->Points - 1))
buf =
sqlite3_mprintf (", %s %s %s %s)", buf_x, buf_y, buf_z,
buf_m);
else
buf =
sqlite3_mprintf (", %s %s %s %s", buf_x, buf_y, buf_z,
buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
static void
gaiaOutEwktPolygon (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg)
{
/* formats an EWKT POLYGON */
char *buf_x;
char *buf_y;
char *buf;
int ib;
int iv;
double x;
double y;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf (",(%s %s", buf_x, buf_y);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s)", buf_x, buf_y);
else
buf = sqlite3_mprintf (",%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
GAIAGEO_DECLARE void
gaiaOutEwktPolygonZ (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg)
{
/* formats an EWKT POLYGONZ */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf;
int ib;
int iv;
double x;
double y;
double z;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s %s", buf_x, buf_y, buf_z);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s %s)", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf (",(%s %s %s", buf_x, buf_y, buf_z);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s %s)", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
static void
gaiaOutEwktPolygonM (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg)
{
/* formats an EWKT POLYGONM */
char *buf_x;
char *buf_y;
char *buf_m;
char *buf;
int ib;
int iv;
double x;
double y;
double m;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv == 0)
buf = sqlite3_mprintf ("(%s %s %s", buf_x, buf_y, buf_m);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s %s)", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv == 0)
buf = sqlite3_mprintf (",(%s %s %s", buf_x, buf_y, buf_m);
else if (iv == (ring->Points - 1))
buf = sqlite3_mprintf (",%s %s %s)", buf_x, buf_y, buf_m);
else
buf = sqlite3_mprintf (",%s %s %s", buf_x, buf_y, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
static void
gaiaOutEwktPolygonZM (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polyg)
{
/* formats an EWKT POLYGONZM */
char *buf_x;
char *buf_y;
char *buf_z;
char *buf_m;
char *buf;
int ib;
int iv;
double x;
double y;
double z;
double m;
gaiaRingPtr ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv == 0)
buf =
sqlite3_mprintf ("(%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
else if (iv == (ring->Points - 1))
buf =
sqlite3_mprintf (",%s %s %s %s)", buf_x, buf_y, buf_z, buf_m);
else
buf =
sqlite3_mprintf (",%s %s %s %s", buf_x, buf_y, buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
buf_x = sqlite3_mprintf ("%1.15f", x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%1.15f", y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%1.15f", z);
gaiaOutClean (buf_z);
buf_m = sqlite3_mprintf ("%1.15f", m);
gaiaOutClean (buf_m);
if (iv == 0)
buf =
sqlite3_mprintf (",(%s %s %s %s", buf_x, buf_y, buf_z,
buf_m);
else if (iv == (ring->Points - 1))
buf =
sqlite3_mprintf (",%s %s %s %s)", buf_x, buf_y, buf_z,
buf_m);
else
buf =
sqlite3_mprintf (",%s %s %s %s", buf_x, buf_y, buf_z,
buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
}
GAIAGEO_DECLARE void
gaiaOutWktEx (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom, int precision)
{
/* prints the WKT representation of current geometry */
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* counting how many POINTs are there */
pts++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counting how many LINESTRINGs are there */
lns++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counting how many POLYGONs are there */
pgs++;
polyg = polyg->Next;
}
if ((pts + lns + pgs) == 1
&& (geom->DeclaredType == GAIA_POINT
|| geom->DeclaredType == GAIA_LINESTRING
|| geom->DeclaredType == GAIA_POLYGON))
{
/* we have only one elementary geometry */
point = geom->FirstPoint;
while (point)
{
if (point->DimensionModel == GAIA_XY_Z)
{
/* processing POINTZ */
gaiaAppendToOutBuffer (out_buf, "POINT Z(");
gaiaOutPointZex (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_M)
{
/* processing POINTM */
gaiaAppendToOutBuffer (out_buf, "POINT M(");
gaiaOutPointM (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
/* processing POINTZM */
gaiaAppendToOutBuffer (out_buf, "POINT ZM(");
gaiaOutPointZM (out_buf, point, precision);
}
else
{
/* processing POINT */
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutPoint (out_buf, point, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if (line->DimensionModel == GAIA_XY_Z)
{
/* processing LINESTRINGZ */
gaiaAppendToOutBuffer (out_buf, "LINESTRING Z(");
gaiaOutLinestringZex (out_buf, line, precision);
}
else if (line->DimensionModel == GAIA_XY_M)
{
/* processing LINESTRINGM */
gaiaAppendToOutBuffer (out_buf, "LINESTRING M(");
gaiaOutLinestringM (out_buf, line, precision);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
/* processing LINESTRINGZM */
gaiaAppendToOutBuffer (out_buf, "LINESTRING ZM(");
gaiaOutLinestringZM (out_buf, line, precision);
}
else
{
/* processing LINESTRING */
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutLinestring (out_buf, line, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if (polyg->DimensionModel == GAIA_XY_Z)
{
/* processing POLYGONZ */
gaiaAppendToOutBuffer (out_buf, "POLYGON Z(");
gaiaOutPolygonZex (out_buf, polyg, precision);
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
/* processing POLYGONM */
gaiaAppendToOutBuffer (out_buf, "POLYGON M(");
gaiaOutPolygonM (out_buf, polyg, precision);
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
/* processing POLYGONZM */
gaiaAppendToOutBuffer (out_buf, "POLYGON ZM(");
gaiaOutPolygonZM (out_buf, polyg, precision);
}
else
{
/* processing POLYGON */
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutPolygon (out_buf, polyg, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
}
else
{
/* we have some kind of complex geometry */
if (pts > 0 && lns == 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTIPOINT)
{
/* some kind of MULTIPOINT */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT Z(");
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT M(");
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT ZM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT(");
point = geom->FirstPoint;
while (point)
{
if (point->DimensionModel == GAIA_XY_Z)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ", ");
gaiaOutPointZex (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_M)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ", ");
gaiaOutPointM (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ", ");
gaiaOutPointZM (out_buf, point, precision);
}
else
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ", ");
gaiaOutPoint (out_buf, point, precision);
}
point = point->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns > 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTILINESTRING)
{
/* some kind of MULTILINESTRING */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING Z(");
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING M(");
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING ZM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING(");
line = geom->FirstLinestring;
while (line)
{
if (line != geom->FirstLinestring)
gaiaAppendToOutBuffer (out_buf, ", (");
else
gaiaAppendToOutBuffer (out_buf, "(");
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaOutLinestringZex (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaOutLinestringM (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaOutLinestringZM (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
gaiaOutLinestring (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
line = line->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns == 0 && pgs > 0
&& geom->DeclaredType == GAIA_MULTIPOLYGON)
{
/* some kind of MULTIPOLYGON */
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON Z(");
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON M(");
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON ZM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON(");
polyg = geom->FirstPolygon;
while (polyg)
{
if (polyg != geom->FirstPolygon)
gaiaAppendToOutBuffer (out_buf, ", (");
else
gaiaAppendToOutBuffer (out_buf, "(");
if (polyg->DimensionModel == GAIA_XY_Z)
{
gaiaOutPolygonZex (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
gaiaOutPolygonM (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
gaiaOutPolygonZM (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
gaiaOutPolygon (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
}
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
/* some kind of GEOMETRYCOLLECTION */
int ie = 0;
if (geom->DimensionModel == GAIA_XY_Z)
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION Z(");
else if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION M(");
else if (geom->DimensionModel == GAIA_XY_Z_M)
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION ZM(");
else
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION(");
point = geom->FirstPoint;
while (point)
{
/* processing POINTs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ", ");
ie++;
if (point->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "POINT Z(");
gaiaOutPointZex (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "POINT M(");
gaiaOutPointM (out_buf, point, precision);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "POINT ZM(");
gaiaOutPointZM (out_buf, point, precision);
}
else
{
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutPoint (out_buf, point, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRINGs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ", ");
ie++;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING Z(");
gaiaOutLinestringZex (out_buf, line, precision);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING M(");
gaiaOutLinestringM (out_buf, line, precision);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING ZM(");
gaiaOutLinestringZM (out_buf, line, precision);
}
else
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutLinestring (out_buf, line, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGONs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ", ");
ie++;
if (polyg->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "POLYGON Z(");
gaiaOutPolygonZex (out_buf, polyg, precision);
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "POLYGON M(");
gaiaOutPolygonM (out_buf, polyg, precision);
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "POLYGON ZM(");
gaiaOutPolygonZM (out_buf, polyg, precision);
}
else
{
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutPolygon (out_buf, polyg, precision);
}
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
}
}
GAIAGEO_DECLARE void
gaiaOutWkt (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom)
{
/*
* prints the WKT representation of current geometry
* convenience method - default decimal precision
*/
gaiaOutWktEx (out_buf, geom, -1);
}
GAIAGEO_DECLARE void
gaiaOutWktStrict (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom, int precision)
{
/*
* prints the WKT representation of current geometry
* strictly conformant 2D WKT implementation
*/
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
if (precision > 18)
precision = 18;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* counting how many POINTs are there */
pts++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counting how many LINESTRINGs are there */
lns++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counting how many POLYGONs are there */
pgs++;
polyg = polyg->Next;
}
if ((pts + lns + pgs) == 1
&& (geom->DeclaredType == GAIA_POINT
|| geom->DeclaredType == GAIA_LINESTRING
|| geom->DeclaredType == GAIA_POLYGON))
{
/* we have only one elementary geometry */
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutPointStrict (out_buf, point, precision);
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutLinestringStrict (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGON */
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutPolygonStrict (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
}
else
{
/* we have some kind of complex geometry */
if (pts > 0 && lns == 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTIPOINT)
{
/* some kind of MULTIPOINT */
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT(");
point = geom->FirstPoint;
while (point)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
gaiaOutPointStrict (out_buf, point, precision);
point = point->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns > 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTILINESTRING)
{
/* some kind of MULTILINESTRING */
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING(");
line = geom->FirstLinestring;
while (line)
{
if (line != geom->FirstLinestring)
gaiaAppendToOutBuffer (out_buf, ",(");
else
gaiaAppendToOutBuffer (out_buf, "(");
gaiaOutLinestringStrict (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns == 0 && pgs > 0
&& geom->DeclaredType == GAIA_MULTIPOLYGON)
{
/* some kind of MULTIPOLYGON */
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON(");
polyg = geom->FirstPolygon;
while (polyg)
{
if (polyg != geom->FirstPolygon)
gaiaAppendToOutBuffer (out_buf, ",(");
else
gaiaAppendToOutBuffer (out_buf, "(");
gaiaOutPolygonStrict (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
/* some kind of GEOMETRYCOLLECTION */
int ie = 0;
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION(");
point = geom->FirstPoint;
while (point)
{
/* processing POINTs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutPointStrict (out_buf, point, precision);
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRINGs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutLinestringStrict (out_buf, line, precision);
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGONs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutPolygonStrict (out_buf, polyg, precision);
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
}
}
GAIAGEO_DECLARE void
gaiaToEWKT (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom)
{
/* prints the EWKT representation of current geometry */
char buf[128];
int pts = 0;
int lns = 0;
int pgs = 0;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
if (!geom)
return;
sprintf (buf, "SRID=%d;", geom->Srid);
gaiaAppendToOutBuffer (out_buf, buf);
point = geom->FirstPoint;
while (point)
{
/* counting how many POINTs are there */
pts++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counting how many LINESTRINGs are there */
lns++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counting how many POLYGONs are there */
pgs++;
polyg = polyg->Next;
}
if ((pts + lns + pgs) == 1
&& (geom->DeclaredType == GAIA_POINT
|| geom->DeclaredType == GAIA_LINESTRING
|| geom->DeclaredType == GAIA_POLYGON))
{
/* we have only one elementary geometry */
point = geom->FirstPoint;
while (point)
{
if (point->DimensionModel == GAIA_XY_Z)
{
/* processing POINTZ */
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPointZ (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_M)
{
/* processing POINTM */
gaiaAppendToOutBuffer (out_buf, "POINTM(");
gaiaOutEwktPointM (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
/* processing POINTZM */
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPointZM (out_buf, point);
}
else
{
/* processing POINT */
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPoint (out_buf, point);
}
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
if (line->DimensionModel == GAIA_XY_Z)
{
/* processing LINESTRINGZ */
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestringZ (out_buf, line);
}
else if (line->DimensionModel == GAIA_XY_M)
{
/* processing LINESTRINGM */
gaiaAppendToOutBuffer (out_buf, "LINESTRINGM(");
gaiaOutEwktLinestringM (out_buf, line);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
/* processing LINESTRINGZM */
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestringZM (out_buf, line);
}
else
{
/* processing LINESTRING */
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestring (out_buf, line);
}
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
if (polyg->DimensionModel == GAIA_XY_Z)
{
/* processing POLYGONZ */
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygonZ (out_buf, polyg);
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
/* processing POLYGONM */
gaiaAppendToOutBuffer (out_buf, "POLYGONM(");
gaiaOutEwktPolygonM (out_buf, polyg);
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
/* processing POLYGONZM */
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygonZM (out_buf, polyg);
}
else
{
/* processing POLYGON */
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygon (out_buf, polyg);
}
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
}
else
{
/* we have some kind of complex geometry */
if (pts > 0 && lns == 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTIPOINT)
{
/* some kind of MULTIPOINT */
if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOINTM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTIPOINT(");
point = geom->FirstPoint;
while (point)
{
if (point->DimensionModel == GAIA_XY_Z)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
gaiaOutEwktPointZ (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_M)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
gaiaOutEwktPointM (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
gaiaOutEwktPointZM (out_buf, point);
}
else
{
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
gaiaOutEwktPoint (out_buf, point);
}
point = point->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns > 0 && pgs == 0
&& geom->DeclaredType == GAIA_MULTILINESTRING)
{
/* some kind of MULTILINESTRING */
if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRINGM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTILINESTRING(");
line = geom->FirstLinestring;
while (line)
{
if (line != geom->FirstLinestring)
gaiaAppendToOutBuffer (out_buf, ",(");
else
gaiaAppendToOutBuffer (out_buf, "(");
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaOutEwktLinestringZ (out_buf, line);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaOutEwktLinestringM (out_buf, line);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaOutEwktLinestringZM (out_buf, line);
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
gaiaOutEwktLinestring (out_buf, line);
gaiaAppendToOutBuffer (out_buf, ")");
}
line = line->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (pts == 0 && lns == 0 && pgs > 0
&& geom->DeclaredType == GAIA_MULTIPOLYGON)
{
/* some kind of MULTIPOLYGON */
if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGONM(");
else
gaiaAppendToOutBuffer (out_buf, "MULTIPOLYGON(");
polyg = geom->FirstPolygon;
while (polyg)
{
if (polyg != geom->FirstPolygon)
gaiaAppendToOutBuffer (out_buf, ",(");
else
gaiaAppendToOutBuffer (out_buf, "(");
if (polyg->DimensionModel == GAIA_XY_Z)
{
gaiaOutEwktPolygonZ (out_buf, polyg);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
gaiaOutEwktPolygonM (out_buf, polyg);
gaiaAppendToOutBuffer (out_buf, ")");
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
gaiaOutEwktPolygonZM (out_buf, polyg);
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
gaiaOutEwktPolygon (out_buf, polyg);
gaiaAppendToOutBuffer (out_buf, ")");
}
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
else
{
/* some kind of GEOMETRYCOLLECTION */
int ie = 0;
if (geom->DimensionModel == GAIA_XY_M)
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTIONM(");
else
gaiaAppendToOutBuffer (out_buf, "GEOMETRYCOLLECTION(");
point = geom->FirstPoint;
while (point)
{
/* processing POINTs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
if (point->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPointZ (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "POINTM(");
gaiaOutEwktPointM (out_buf, point);
}
else if (point->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPointZM (out_buf, point);
}
else
{
gaiaAppendToOutBuffer (out_buf, "POINT(");
gaiaOutEwktPoint (out_buf, point);
}
gaiaAppendToOutBuffer (out_buf, ")");
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRINGs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
if (line->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestringZ (out_buf, line);
}
else if (line->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRINGM(");
gaiaOutEwktLinestringM (out_buf, line);
}
else if (line->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestringZM (out_buf, line);
}
else
{
gaiaAppendToOutBuffer (out_buf, "LINESTRING(");
gaiaOutEwktLinestring (out_buf, line);
}
gaiaAppendToOutBuffer (out_buf, ")");
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGONs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ",");
ie++;
if (polyg->DimensionModel == GAIA_XY_Z)
{
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygonZ (out_buf, polyg);
}
else if (polyg->DimensionModel == GAIA_XY_M)
{
gaiaAppendToOutBuffer (out_buf, "POLYGONM(");
gaiaOutEwktPolygonM (out_buf, polyg);
}
else if (polyg->DimensionModel == GAIA_XY_Z_M)
{
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygonZM (out_buf, polyg);
}
else
{
gaiaAppendToOutBuffer (out_buf, "POLYGON(");
gaiaOutEwktPolygon (out_buf, polyg);
}
gaiaAppendToOutBuffer (out_buf, ")");
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, ")");
}
}
}
/*
/
/ Gaia common support for SVG encoded geometries
/
////////////////////////////////////////////////////////////
/
/ Author: Klaus Foerster klaus.foerster@svg.cc
/ version 0.9. 2008 September 21
/
*/
static void
SvgCoords (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats POINT as SVG-attributes x,y */
char *buf_x;
char *buf_y;
char *buf;
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y * -1);
gaiaOutClean (buf_y);
buf = sqlite3_mprintf ("x=\"%s\" y=\"%s\"", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
SvgCircle (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats POINT as SVG-attributes cx,cy */
char *buf_x;
char *buf_y;
char *buf;
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y * -1);
gaiaOutClean (buf_y);
buf = sqlite3_mprintf ("cx=\"%s\" cy=\"%s\"", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
static void
SvgPathRelative (gaiaOutBufferPtr out_buf, int dims, int points, double *coords,
int precision, int closePath)
{
/* formats LINESTRING as SVG-path d-attribute with relative coordinate moves */
char *buf_x;
char *buf_y;
char *buf;
double x;
double y;
double z;
double m;
double lastX = 0.0;
double lastY = 0.0;
int iv;
for (iv = 0; iv < points; iv++)
{
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv, &x, &y, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv, &x, &y, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (coords, iv, &x, &y);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x - lastX);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, (y - lastY) * -1);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("M %s %s l ", buf_x, buf_y);
else
buf = sqlite3_mprintf ("%s %s ", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
lastX = x;
lastY = y;
if (iv == points - 1 && closePath == 1)
gaiaAppendToOutBuffer (out_buf, "z ");
else
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
static void
SvgPathAbsolute (gaiaOutBufferPtr out_buf, int dims, int points, double *coords,
int precision, int closePath)
{
/* formats LINESTRING as SVG-path d-attribute with relative coordinate moves */
char *buf_x;
char *buf_y;
char *buf;
double x;
double y;
double z;
double m;
int iv;
for (iv = 0; iv < points; iv++)
{
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv, &x, &y, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv, &x, &y, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (coords, iv, &x, &y);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y * -1);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("M %s %s L ", buf_x, buf_y);
else
buf = sqlite3_mprintf ("%s %s ", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
if (iv == points - 1 && closePath == 1)
gaiaAppendToOutBuffer (out_buf, "z ");
else
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
}
GAIAGEO_DECLARE void
gaiaOutSvg (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom, int relative,
int precision)
{
/* prints the SVG representation of current geometry */
int pts = 0;
int lns = 0;
int pgs = 0;
int ib;
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
if (precision > 18)
precision = 18;
if (!geom)
return;
point = geom->FirstPoint;
while (point)
{
/* counting how many POINTs are there */
pts++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* counting how many LINESTRINGs are there */
lns++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* counting how many POLYGONs are there */
pgs++;
polyg = polyg->Next;
}
if ((pts + lns + pgs) == 1)
{
/* we have only one elementary geometry */
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
if (relative == 1)
SvgCoords (out_buf, point, precision);
else
SvgCircle (out_buf, point, precision);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
if (relative == 1)
SvgPathRelative (out_buf, line->DimensionModel,
line->Points, line->Coords, precision, 0);
else
SvgPathAbsolute (out_buf, line->DimensionModel,
line->Points, line->Coords, precision, 0);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* process exterior and interior rings */
ring = polyg->Exterior;
if (relative == 1)
{
SvgPathRelative (out_buf, ring->DimensionModel,
ring->Points, ring->Coords, precision,
1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathRelative (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
else
{
SvgPathAbsolute (out_buf, ring->DimensionModel,
ring->Points, ring->Coords, precision,
1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathAbsolute (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
polyg = polyg->Next;
}
}
else
{
/* we have some kind of complex geometry */
if (pts > 0 && lns == 0 && pgs == 0)
{
/* this one is a MULTIPOINT */
point = geom->FirstPoint;
while (point)
{
/* processing POINTs */
if (point != geom->FirstPoint)
gaiaAppendToOutBuffer (out_buf, ",");
if (relative == 1)
SvgCoords (out_buf, point, precision);
else
SvgCircle (out_buf, point, precision);
point = point->Next;
}
}
else if (pts == 0 && lns > 0 && pgs == 0)
{
/* this one is a MULTILINESTRING */
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRINGs */
if (relative == 1)
SvgPathRelative (out_buf, line->DimensionModel,
line->Points, line->Coords,
precision, 0);
else
SvgPathAbsolute (out_buf, line->DimensionModel,
line->Points, line->Coords,
precision, 0);
line = line->Next;
}
}
else if (pts == 0 && lns == 0 && pgs > 0)
{
/* this one is a MULTIPOLYGON */
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGONs */
ring = polyg->Exterior;
if (relative == 1)
{
SvgPathRelative (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathRelative (out_buf,
ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
else
{
SvgPathAbsolute (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathAbsolute (out_buf,
ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
polyg = polyg->Next;
}
}
else
{
/* this one is a GEOMETRYCOLLECTION */
int ie = 0;
point = geom->FirstPoint;
while (point)
{
/* processing POINTs */
if (ie > 0)
{
gaiaAppendToOutBuffer (out_buf, ";");
}
ie++;
if (relative == 1)
SvgCoords (out_buf, point, precision);
else
SvgCircle (out_buf, point, precision);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRINGs */
if (ie > 0)
gaiaAppendToOutBuffer (out_buf, ";");
ie++;
if (relative == 1)
SvgPathRelative (out_buf, line->DimensionModel,
line->Points, line->Coords,
precision, 0);
else
SvgPathAbsolute (out_buf, line->DimensionModel,
line->Points, line->Coords,
precision, 0);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGONs */
ie++;
/* process exterior and interior rings */
ring = polyg->Exterior;
if (relative == 1)
{
SvgPathRelative (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathRelative (out_buf,
ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
else
{
SvgPathAbsolute (out_buf, ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
ring = polyg->Interiors + ib;
SvgPathAbsolute (out_buf,
ring->DimensionModel,
ring->Points, ring->Coords,
precision, 1);
}
}
polyg = polyg->Next;
}
}
}
if (out_buf->Error == 0 && out_buf->WriteOffset > 0)
{
/* sandro 2012-02-23 cleaning extra trailing spaces */
int i;
for (i = out_buf->WriteOffset - 1; i >= 0; i--)
{
if (*(out_buf->Buffer + i) == ' ')
{
*(out_buf->Buffer + i) = '\0';
out_buf->WriteOffset -= 1;
}
else
break;
}
}
}
/* END of Klaus Foerster SVG implementation */
static char *
XmlClean (const char *string)
{
/* well formatting a text string for XML */
int ind;
char *clean;
char *p_out;
int len = strlen (string);
clean = malloc (len * 3);
if (!clean)
return NULL;
p_out = clean;
for (ind = 0; ind < len; ind++)
{
/* masking XML special chars */
switch (string[ind])
{
case '&':
*p_out++ = '&';
*p_out++ = 'a';
*p_out++ = 'm';
*p_out++ = 'p';
*p_out++ = ';';
break;
case '<':
*p_out++ = '&';
*p_out++ = 'l';
*p_out++ = 't';
*p_out++ = ';';
break;
case '>':
*p_out++ = '&';
*p_out++ = 'g';
*p_out++ = 't';
*p_out++ = ';';
break;
case '"':
*p_out++ = '&';
*p_out++ = 'q';
*p_out++ = 'u';
*p_out++ = 'o';
*p_out++ = 't';
*p_out++ = ';';
break;
default:
*p_out++ = string[ind];
break;
};
}
*p_out = '\0';
return clean;
}
static void
out_kml_point (gaiaOutBufferPtr out_buf, gaiaPointPtr point, int precision)
{
/* formats POINT as KML [x,y] */
char *buf_x = NULL;
char *buf_y = NULL;
char *buf_z = NULL;
char *buf = NULL;
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, point->Z);
gaiaOutClean (buf_z);
}
gaiaAppendToOutBuffer (out_buf, "");
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
{
buf = sqlite3_mprintf ("%s,%s,%s", buf_x, buf_y, buf_z);
sqlite3_free (buf_z);
}
else
buf = sqlite3_mprintf ("%s,%s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
gaiaAppendToOutBuffer (out_buf, "");
}
static void
out_kml_linestring (gaiaOutBuffer * out_buf, int dims, int points,
double *coords, int precision)
{
/* formats LINESTRING as KML [x,y] */
char *buf_x = NULL;
char *buf_y = NULL;
char *buf_z = NULL;
char *buf = NULL;
int iv;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
gaiaAppendToOutBuffer (out_buf, "");
for (iv = 0; iv < points; iv++)
{
/* exporting vertices */
if (dims == GAIA_XY_Z)
{
gaiaGetPointXYZ (coords, iv, &x, &y, &z);
}
else if (dims == GAIA_XY_M)
{
gaiaGetPointXYM (coords, iv, &x, &y, &m);
}
else if (dims == GAIA_XY_Z_M)
{
gaiaGetPointXYZM (coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (coords, iv, &x, &y);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (dims == GAIA_XY_Z || dims == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf ("%s,%s,%s", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (" %s,%s,%s", buf_x, buf_y, buf_z);
sqlite3_free (buf_z);
}
else
{
if (iv == 0)
buf = sqlite3_mprintf ("%s,%s", buf_x, buf_y);
else
buf = sqlite3_mprintf (" %s,%s", buf_x, buf_y);
}
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
gaiaAppendToOutBuffer (out_buf, "");
}
static void
out_kml_polygon (gaiaOutBufferPtr out_buf, gaiaPolygonPtr polygon,
int precision)
{
/* formats POLYGON as KML [x,y] */
char *buf_x = NULL;
char *buf_y = NULL;
char *buf_z = NULL;
char *buf = NULL;
gaiaRingPtr ring;
int iv;
int ib;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double m = 0.0;
gaiaAppendToOutBuffer (out_buf, "");
gaiaAppendToOutBuffer (out_buf,
"");
ring = polygon->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [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);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (ring->DimensionModel == GAIA_XY_Z
|| ring->DimensionModel == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf = sqlite3_mprintf ("%s,%s,%s", buf_x, buf_y, buf_z);
else
buf = sqlite3_mprintf (" %s,%s,%s", buf_x, buf_y, buf_z);
sqlite3_free (buf_z);
}
else
{
if (iv == 0)
buf = sqlite3_mprintf ("%s,%s", buf_x, buf_y);
else
buf = sqlite3_mprintf (" %s,%s", buf_x, buf_y);
}
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
gaiaAppendToOutBuffer (out_buf,
"");
for (ib = 0; ib < polygon->NumInteriors; ib++)
{
/* interior rings */
ring = polygon->Interiors + ib;
gaiaAppendToOutBuffer (out_buf,
"");
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [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);
}
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (ring->DimensionModel == GAIA_XY_Z
|| ring->DimensionModel == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf =
sqlite3_mprintf ("%s,%s,%s", buf_x, buf_y, buf_z);
else
buf =
sqlite3_mprintf (" %s,%s,%s", buf_x, buf_y,
buf_z);
sqlite3_free (buf_z);
}
else
{
if (iv == 0)
buf = sqlite3_mprintf ("%s,%s", buf_x, buf_y);
else
buf = sqlite3_mprintf (" %s,%s", buf_x, buf_y);
}
sqlite3_free (buf_x);
sqlite3_free (buf_y);
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
gaiaAppendToOutBuffer (out_buf,
"");
}
gaiaAppendToOutBuffer (out_buf, "");
}
GAIAGEO_DECLARE void
gaiaOutFullKml (gaiaOutBufferPtr out_buf, const char *name, const char *desc,
gaiaGeomCollPtr geom, int precision)
{
/* prints the 'full' KML representation of current geometry */
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
int count = 0;
char *xml_clean;
if (!geom)
return;
if (precision > 18)
precision = 18;
/* counting how many elementary geometries are there */
point = geom->FirstPoint;
while (point)
{
count++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
count++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
count++;
polyg = polyg->Next;
}
if (count == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOINT ||
geom->DeclaredType == GAIA_MULTILINESTRING ||
geom->DeclaredType == GAIA_MULTIPOLYGON ||
geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
count = 2;
}
gaiaAppendToOutBuffer (out_buf, "");
xml_clean = XmlClean (name);
if (xml_clean)
{
gaiaAppendToOutBuffer (out_buf, xml_clean);
free (xml_clean);
}
else
gaiaAppendToOutBuffer (out_buf, " ");
gaiaAppendToOutBuffer (out_buf, "");
xml_clean = XmlClean (desc);
if (xml_clean)
{
gaiaAppendToOutBuffer (out_buf, xml_clean);
free (xml_clean);
}
else
gaiaAppendToOutBuffer (out_buf, " ");
gaiaAppendToOutBuffer (out_buf, "");
if (count > 1)
{
/* MultiGeometry start */
gaiaAppendToOutBuffer (out_buf, "");
}
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
out_kml_point (out_buf, point, precision);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
out_kml_linestring (out_buf, line->DimensionModel,
line->Points, line->Coords, precision);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGON */
out_kml_polygon (out_buf, polyg, precision);
polyg = polyg->Next;
}
if (count > 1)
{
/* MultiGeometry end */
gaiaAppendToOutBuffer (out_buf, "");
}
gaiaAppendToOutBuffer (out_buf, "");
}
GAIAGEO_DECLARE void
gaiaOutBareKml (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom, int precision)
{
/* prints the 'bare' KML representation of current geometry */
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
int count = 0;
if (!geom)
return;
if (precision > 18)
precision = 18;
/* counting how many elementary geometries are there */
point = geom->FirstPoint;
while (point)
{
count++;
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
count++;
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
count++;
polyg = polyg->Next;
}
if (count == 1)
{
if (geom->DeclaredType == GAIA_MULTIPOINT ||
geom->DeclaredType == GAIA_MULTILINESTRING ||
geom->DeclaredType == GAIA_MULTIPOLYGON ||
geom->DeclaredType == GAIA_GEOMETRYCOLLECTION)
count = 2;
}
if (count > 1)
{
/* MultiGeometry start */
gaiaAppendToOutBuffer (out_buf, "");
}
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
out_kml_point (out_buf, point, precision);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
out_kml_linestring (out_buf, line->DimensionModel, line->Points,
line->Coords, precision);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGON */
out_kml_polygon (out_buf, polyg, precision);
polyg = polyg->Next;
}
if (count > 1)
{
/* MultiGeometry end */
gaiaAppendToOutBuffer (out_buf, "");
}
}
GAIAGEO_DECLARE void
gaiaOutGml (gaiaOutBufferPtr out_buf, int version, int precision,
gaiaGeomCollPtr geom)
{
/*
/ prints the GML representation of current geometry
/ jusrt an alias name for gaiaOutGml_ex with FLIPPED=FALSE
*/
gaiaOutGml_ex (out_buf, version, 0, precision, geom);
}
GAIAGEO_DECLARE void
gaiaOutGml_ex (gaiaOutBufferPtr out_buf, int version, int flipped,
int precision, gaiaGeomCollPtr geom)
{
/*
/ prints the GML representation of current geometry
/ *result* returns the encoded GML or NULL if any error is encountered
*/
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
int iv;
int ib;
double x;
double y;
double z;
double m;
int has_z;
int is_multi = 1;
int is_coll = 0;
char buf[2048];
char *xbuf;
char *buf_x;
char *buf_y;
char *buf_z;
if (!geom)
return;
if (precision > 18)
precision = 18;
switch (geom->DeclaredType)
{
case GAIA_POINT:
case GAIA_LINESTRING:
case GAIA_POLYGON:
*buf = '\0';
is_multi = 0;
break;
case GAIA_MULTIPOINT:
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
break;
case GAIA_MULTILINESTRING:
if (version == 3)
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
}
else
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
}
break;
case GAIA_MULTIPOLYGON:
if (version == 3)
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
}
else
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
}
break;
default:
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
is_coll = 1;
break;
};
gaiaAppendToOutBuffer (out_buf, buf);
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
if (is_multi)
{
if (is_coll)
strcpy (buf, "");
else
strcpy (buf, "");
strcat (buf, "");
}
else
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
}
if (version == 3)
{
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
strcat (buf, "");
gaiaAppendToOutBuffer (out_buf, buf);
if (flipped)
{
buf_x = sqlite3_mprintf ("%.*f", precision, point->Y);
buf_y = sqlite3_mprintf ("%.*f", precision, point->X);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, point->Z);
gaiaOutClean (buf_z);
if (version == 3)
{
xbuf = sqlite3_mprintf ("%s %s %s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
xbuf = sqlite3_mprintf ("%s,%s,%s", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
}
else
{
if (version == 3)
{
xbuf = sqlite3_mprintf ("%s %s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
else
{
xbuf = sqlite3_mprintf ("%s,%s", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
}
gaiaAppendToOutBuffer (out_buf, xbuf);
sqlite3_free (xbuf);
if (version == 3)
strcpy (buf, "");
else
strcpy (buf, "");
if (is_multi)
{
strcat (buf, "");
if (is_coll)
strcat (buf, "");
else
strcat (buf, "");
}
else
strcat (buf, "");
gaiaAppendToOutBuffer (out_buf, buf);
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
if (is_multi)
{
if (version == 3)
{
if (is_coll)
strcpy (buf, "");
else
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
if (line->DimensionModel == GAIA_XY_Z
|| line->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
if (is_coll)
strcpy (buf, "");
else
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
}
else
{
if (version == 3)
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
strcat (buf, "");
strcat (buf, "");
if (line->DimensionModel == GAIA_XY_Z
|| line->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
strcat (buf, "");
}
}
gaiaAppendToOutBuffer (out_buf, buf);
for (iv = 0; iv < line->Points; iv++)
{
/* exporting vertices */
has_z = 0;
z = 0.0;
if (line->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
if (iv == 0)
*buf = '\0';
else
strcpy (buf, " ");
if (has_z)
{
if (flipped)
{
buf_x = sqlite3_mprintf ("%.*f", precision, y);
buf_y = sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s %s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s,%s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
}
else
{
if (flipped)
{
buf_x = sqlite3_mprintf ("%.*f", precision, y);
buf_y = sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s", buf, buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s", buf, buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
}
gaiaAppendToOutBuffer (out_buf, xbuf);
sqlite3_free (xbuf);
}
if (is_multi)
{
if (version == 3)
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
if (is_coll)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
strcpy (buf, "");
strcat (buf, "");
if (is_coll)
strcat (buf, "");
else
strcat (buf, "");
}
}
else
{
if (version == 3)
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
}
else
{
strcpy (buf, "");
strcat (buf, "");
}
}
gaiaAppendToOutBuffer (out_buf, buf);
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGON */
ring = polyg->Exterior;
if (is_multi)
{
if (version == 3)
{
if (is_coll)
strcpy (buf, "");
else
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
if (ring->DimensionModel == GAIA_XY_Z
|| ring->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
if (is_coll)
strcpy (buf, "");
else
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
}
}
else
{
if (geom->Srid <= 0)
strcpy (buf, "");
else
sprintf (buf,
"",
geom->Srid);
if (version == 3)
{
strcat (buf, "");
strcat (buf, "");
if (ring->DimensionModel == GAIA_XY_Z
|| ring->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
strcat (buf, "");
strcat (buf, "");
strcat (buf, "");
}
}
gaiaAppendToOutBuffer (out_buf, buf);
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [Interior Ring] */
has_z = 0;
z = 0.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
}
if (iv == 0)
*buf = '\0';
else
strcpy (buf, " ");
if (has_z)
{
if (flipped)
{
buf_x = sqlite3_mprintf ("%.*f", precision, y);
buf_y = sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s %s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s,%s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
}
else
{
if (flipped)
{
buf_x = sqlite3_mprintf ("%.*f", precision, y);
buf_y = sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s", buf, buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s", buf, buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
}
gaiaAppendToOutBuffer (out_buf, xbuf);
sqlite3_free (xbuf);
}
/* closing the Exterior Ring */
if (version == 3)
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
else
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
gaiaAppendToOutBuffer (out_buf, buf);
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* interior rings */
ring = polyg->Interiors + ib;
if (version == 3)
{
strcpy (buf, "");
strcat (buf, "");
if (ring->DimensionModel == GAIA_XY_Z
|| ring->DimensionModel == GAIA_XY_Z_M)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
gaiaAppendToOutBuffer (out_buf, buf);
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [Interior Ring] */
has_z = 0;
z = 0.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
}
if (iv == 0)
*buf = '\0';
else
strcpy (buf, " ");
if (has_z)
{
if (flipped)
{
buf_x =
sqlite3_mprintf ("%.*f", precision, y);
buf_y =
sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x =
sqlite3_mprintf ("%.*f", precision, x);
buf_y =
sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s %s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s,%s", buf, buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
}
else
{
if (flipped)
{
buf_x =
sqlite3_mprintf ("%.*f", precision, y);
buf_y =
sqlite3_mprintf ("%.*f", precision, x);
}
else
{
buf_x =
sqlite3_mprintf ("%.*f", precision, x);
buf_y =
sqlite3_mprintf ("%.*f", precision, y);
}
gaiaOutClean (buf_x);
gaiaOutClean (buf_y);
if (version == 3)
{
xbuf =
sqlite3_mprintf ("%s%s %s", buf, buf_x,
buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
else
{
xbuf =
sqlite3_mprintf ("%s%s,%s", buf, buf_x,
buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
}
gaiaAppendToOutBuffer (out_buf, xbuf);
sqlite3_free (xbuf);
}
/* closing the Interior Ring */
if (version == 3)
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
else
{
strcpy (buf, "");
strcat (buf, "");
strcat (buf, "");
}
gaiaAppendToOutBuffer (out_buf, buf);
}
/* closing the Polygon */
if (is_multi)
{
if (version == 3)
{
strcpy (buf, "");
if (is_coll)
strcat (buf, "");
else
strcat (buf, "");
}
else
{
strcpy (buf, "");
if (is_coll)
strcat (buf, "");
else
strcat (buf, "");
}
}
else
strcpy (buf, "");
gaiaAppendToOutBuffer (out_buf, buf);
polyg = polyg->Next;
}
switch (geom->DeclaredType)
{
case GAIA_POINT:
case GAIA_LINESTRING:
case GAIA_POLYGON:
*buf = '\0';
break;
case GAIA_MULTIPOINT:
sprintf (buf, "");
break;
case GAIA_MULTILINESTRING:
if (version == 3)
sprintf (buf, "");
else
sprintf (buf, "");
break;
case GAIA_MULTIPOLYGON:
if (version == 3)
sprintf (buf, "");
else
sprintf (buf, "");
break;
default:
sprintf (buf, "");
break;
};
gaiaAppendToOutBuffer (out_buf, buf);
}
GAIAGEO_DECLARE void
gaiaOutGeoJSON (gaiaOutBufferPtr out_buf, gaiaGeomCollPtr geom, int precision,
int options)
{
/*
/ prints the GeoJSON representation of current geometry
/ *result* returns the encoded GeoJSON or NULL if any error is encountered
*/
gaiaPointPtr point;
gaiaLinestringPtr line;
gaiaPolygonPtr polyg;
gaiaRingPtr ring;
int iv;
int ib;
double x;
double y;
double z;
double m;
int has_z;
int is_multi = 0;
int multi_count = 0;
char *bbox;
char crs[2048];
char *buf;
char *buf_x;
char *buf_y;
char *buf_m;
char *buf_z = NULL;
char endJson[16];
if (!geom)
return;
if (precision > 18)
precision = 18;
if (options != 0)
{
bbox = NULL;
*crs = '\0';
if (geom->Srid > 0)
{
if (options == 2 || options == 3)
{
/* including short CRS */
sprintf (crs,
",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:%d\"}}",
geom->Srid);
}
if (options == 4 || options == 5)
{
/* including long CRS */
sprintf (crs,
",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"urn:ogc:def:crs:EPSG:%d\"}}",
geom->Srid);
}
}
if (options == 1 || options == 3 || options == 5)
{
/* including BBOX */
gaiaMbrGeometry (geom);
buf_x = sqlite3_mprintf ("%.*f", precision, geom->MinX);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, geom->MinY);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, geom->MaxX);
gaiaOutClean (buf_z);
buf_m = sqlite3_mprintf ("%.*f", precision, geom->MaxY);
gaiaOutClean (buf_m);
bbox =
sqlite3_mprintf (",\"bbox\":[%s,%s,%s,%s]", buf_x, buf_y,
buf_z, buf_m);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
sqlite3_free (buf_m);
}
switch (geom->DeclaredType)
{
case GAIA_POINT:
buf =
sqlite3_mprintf ("{\"type\":\"Point\"%s%s,\"coordinates\":",
crs, bbox);
strcpy (endJson, "}");
break;
case GAIA_LINESTRING:
buf =
sqlite3_mprintf
("{\"type\":\"LineString\"%s%s,\"coordinates\":[", crs,
bbox);
strcpy (endJson, "}");
break;
case GAIA_POLYGON:
buf =
sqlite3_mprintf
("{\"type\":\"Polygon\"%s%s,\"coordinates\":[", crs, bbox);
strcpy (endJson, "}");
break;
case GAIA_MULTIPOINT:
buf =
sqlite3_mprintf
("{\"type\":\"MultiPoint\"%s%s,\"coordinates\":[", crs,
bbox);
strcpy (endJson, "]}");
break;
case GAIA_MULTILINESTRING:
buf =
sqlite3_mprintf
("{\"type\":\"MultiLineString\"%s%s,\"coordinates\":[[",
crs, bbox);
strcpy (endJson, "]}");
break;
case GAIA_MULTIPOLYGON:
buf =
sqlite3_mprintf
("{\"type\":\"MultiPolygon\"%s%s,\"coordinates\":[[", crs,
bbox);
strcpy (endJson, "]}");
break;
default:
buf =
sqlite3_mprintf
("{\"type\":\"GeometryCollection\"%s%s,\"geometries\":[",
crs, bbox);
strcpy (endJson, "]}");
is_multi = 1;
break;
};
if (bbox)
sqlite3_free (bbox);
}
else
{
/* omitting BBOX */
switch (geom->DeclaredType)
{
case GAIA_POINT:
buf = sqlite3_mprintf ("{\"type\":\"Point\",\"coordinates\":");
strcpy (endJson, "}");
break;
case GAIA_LINESTRING:
buf =
sqlite3_mprintf
("{\"type\":\"LineString\",\"coordinates\":[");
strcpy (endJson, "}");
break;
case GAIA_POLYGON:
buf =
sqlite3_mprintf ("{\"type\":\"Polygon\",\"coordinates\":[");
strcpy (endJson, "}");
break;
case GAIA_MULTIPOINT:
buf =
sqlite3_mprintf
("{\"type\":\"MultiPoint\",\"coordinates\":[");
strcpy (endJson, "]}");
break;
case GAIA_MULTILINESTRING:
buf =
sqlite3_mprintf
("{\"type\":\"MultiLineString\",\"coordinates\":[[");
strcpy (endJson, "]}");
break;
case GAIA_MULTIPOLYGON:
buf =
sqlite3_mprintf
("{\"type\":\"MultiPolygon\",\"coordinates\":[[");
strcpy (endJson, "]}");
break;
default:
buf =
sqlite3_mprintf
("{\"type\":\"GeometryCollection\",\"geometries\":[");
strcpy (endJson, "]}");
is_multi = 1;
break;
};
}
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
point = geom->FirstPoint;
while (point)
{
/* processing POINT */
if (is_multi)
{
if (multi_count > 0)
buf = ",{\"type\":\"Point\",\"coordinates\":";
else
buf = "{\"type\":\"Point\",\"coordinates\":";
gaiaAppendToOutBuffer (out_buf, buf);
}
else if (point != geom->FirstPoint)
{
/* adding a further Point */
gaiaAppendToOutBuffer (out_buf, ",");
}
buf_x = sqlite3_mprintf ("%.*f", precision, point->X);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, point->Y);
gaiaOutClean (buf_y);
has_z = 0;
if (point->DimensionModel == GAIA_XY_Z
|| point->DimensionModel == GAIA_XY_Z_M)
{
buf_z = sqlite3_mprintf ("%.*f", precision, point->Z);
gaiaOutClean (buf_z);
has_z = 1;
}
if (has_z)
{
buf = sqlite3_mprintf ("[%s,%s,%s]", buf_x, buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
buf = sqlite3_mprintf ("[%s,%s]", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
if (is_multi)
{
gaiaAppendToOutBuffer (out_buf, "}");
multi_count++;
}
point = point->Next;
}
line = geom->FirstLinestring;
while (line)
{
/* processing LINESTRING */
if (is_multi)
{
if (multi_count > 0)
buf = ",{\"type\":\"LineString\",\"coordinates\":[";
else
buf = "{\"type\":\"LineString\",\"coordinates\":[";
gaiaAppendToOutBuffer (out_buf, buf);
}
else if (line != geom->FirstLinestring)
{
/* opening a further LineString */
gaiaAppendToOutBuffer (out_buf, ",[");
}
for (iv = 0; iv < line->Points; iv++)
{
/* exporting vertices */
has_z = 0;
z = 0.0;
if (line->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (line->Coords, iv, &x, &y);
}
if (has_z)
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf =
sqlite3_mprintf ("[%s,%s,%s]", buf_x, buf_y,
buf_z);
else
buf =
sqlite3_mprintf (",[%s,%s,%s]", buf_x, buf_y,
buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("[%s,%s]", buf_x, buf_y);
else
buf = sqlite3_mprintf (",[%s,%s]", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
/* closing the LineString */
gaiaAppendToOutBuffer (out_buf, "]");
if (is_multi)
{
gaiaAppendToOutBuffer (out_buf, "}");
multi_count++;
}
line = line->Next;
}
polyg = geom->FirstPolygon;
while (polyg)
{
/* processing POLYGON */
if (is_multi)
{
if (multi_count > 0)
buf = ",{\"type\":\"Polygon\",\"coordinates\":[";
else
buf = "{\"type\":\"Polygon\",\"coordinates\":[";
gaiaAppendToOutBuffer (out_buf, buf);
}
else if (polyg != geom->FirstPolygon)
{
/* opening a further Polygon */
gaiaAppendToOutBuffer (out_buf, ",[");
}
ring = polyg->Exterior;
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [Interior Ring] */
has_z = 0;
z = 0.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
}
if (has_z)
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf =
sqlite3_mprintf ("[[%s,%s,%s]", buf_x, buf_y,
buf_z);
else
buf =
sqlite3_mprintf (",[%s,%s,%s]", buf_x, buf_y,
buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf = sqlite3_mprintf ("[[%s,%s]", buf_x, buf_y);
else
buf = sqlite3_mprintf (",[%s,%s]", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
/* closing the Exterior Ring */
gaiaAppendToOutBuffer (out_buf, "]");
for (ib = 0; ib < polyg->NumInteriors; ib++)
{
/* interior rings */
ring = polyg->Interiors + ib;
for (iv = 0; iv < ring->Points; iv++)
{
/* exporting vertices [Interior Ring] */
has_z = 0;
z = 0.0;
if (ring->DimensionModel == GAIA_XY_Z)
{
has_z = 1;
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)
{
has_z = 1;
gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m);
}
else
{
gaiaGetPoint (ring->Coords, iv, &x, &y);
}
if (has_z)
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
buf_z = sqlite3_mprintf ("%.*f", precision, z);
gaiaOutClean (buf_z);
if (iv == 0)
buf =
sqlite3_mprintf (",[[%s,%s,%s]", buf_x,
buf_y, buf_z);
else
buf =
sqlite3_mprintf (",[%s,%s,%s]", buf_x,
buf_y, buf_z);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
sqlite3_free (buf_z);
}
else
{
buf_x = sqlite3_mprintf ("%.*f", precision, x);
gaiaOutClean (buf_x);
buf_y = sqlite3_mprintf ("%.*f", precision, y);
gaiaOutClean (buf_y);
if (iv == 0)
buf =
sqlite3_mprintf (",[[%s,%s]", buf_x, buf_y);
else
buf =
sqlite3_mprintf (",[%s,%s]", buf_x, buf_y);
sqlite3_free (buf_x);
sqlite3_free (buf_y);
}
gaiaAppendToOutBuffer (out_buf, buf);
sqlite3_free (buf);
}
/* closing the Interior Ring */
gaiaAppendToOutBuffer (out_buf, "]");
}
/* closing the Polygon */
gaiaAppendToOutBuffer (out_buf, "]");
if (is_multi)
{
gaiaAppendToOutBuffer (out_buf, "}");
multi_count++;
}
polyg = polyg->Next;
}
gaiaAppendToOutBuffer (out_buf, endJson);
}
libspatialite-5.1.0/src/gaiageo/gg_vanuatu.c 0000644 0001750 0001750 00000171240 14463127014 015762 0000000 0000000 /*
gg_vanuatu.c -- WKT parser/lexer
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved.
The Vanuatu Team - University of Toronto - Supervisor:
Greg Wilson gvwilson@cs.toronto.ca
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#if defined(_WIN32) || defined(WIN32)
#include
#ifndef isatty
#define isatty _isatty
#endif
#ifndef fileno
#define fileno _fileno
#endif
#endif
#define VANUATU_DYN_NONE 0
#define VANUATU_DYN_POINT 1
#define VANUATU_DYN_LINESTRING 2
#define VANUATU_DYN_POLYGON 3
#define VANUATU_DYN_RING 4
#define VANUATU_DYN_GEOMETRY 5
#define VANUATU_DYN_BLOCK 1024
/*
** CAVEAT: we must redefine any Lemon/Flex own macro
*/
#define YYMINORTYPE VANUATU_MINORTYPE
#define YY_CHAR VANUATU_YY_CHAR
#define input vanuatu_input
#define ParseAlloc vanuatuParseAlloc
#define ParseFree vanuatuParseFree
#define ParseStackPeak vanuatuParseStackPeak
#define Parse vanuatuParse
#define yyStackEntry vanuatu_yyStackEntry
#define yyzerominor vanuatu_yyzerominor
#define yy_accept vanuatu_yy_accept
#define yy_action vanuatu_yy_action
#define yy_base vanuatu_yy_base
#define yy_buffer_stack vanuatu_yy_buffer_stack
#define yy_buffer_stack_max vanuatu_yy_buffer_stack_max
#define yy_buffer_stack_top vanuatu_yy_buffer_stack_top
#define yy_c_buf_p vanuatu_yy_c_buf_p
#define yy_chk vanuatu_yy_chk
#define yy_def vanuatu_yy_def
#define yy_default vanuatu_yy_default
#define yy_destructor vanuatu_yy_destructor
#define yy_ec vanuatu_yy_ec
#define yy_fatal_error vanuatu_yy_fatal_error
#define yy_find_reduce_action vanuatu_yy_find_reduce_action
#define yy_find_shift_action vanuatu_yy_find_shift_action
#define yy_get_next_buffer vanuatu_yy_get_next_buffer
#define yy_get_previous_state vanuatu_yy_get_previous_state
#define yy_init vanuatu_yy_init
#define yy_init_globals vanuatu_yy_init_globals
#define yy_lookahead vanuatu_yy_lookahead
#define yy_meta vanuatu_yy_meta
#define yy_nxt vanuatu_yy_nxt
#define yy_parse_failed vanuatu_yy_parse_failed
#define yy_pop_parser_stack vanuatu_yy_pop_parser_stack
#define yy_reduce vanuatu_yy_reduce
#define yy_reduce_ofst vanuatu_yy_reduce_ofst
#define yy_shift vanuatu_yy_shift
#define yy_shift_ofst vanuatu_yy_shift_ofst
#define yy_start vanuatu_yy_start
#define yy_state_type vanuatu_yy_state_type
#define yy_syntax_error vanuatu_yy_syntax_error
#define yy_trans_info vanuatu_yy_trans_info
#define yy_try_NUL_trans vanuatu_yy_try_NUL_trans
#define yyParser vanuatu_yyParser
#define yyStackEntry vanuatu_yyStackEntry
#define yyStackOverflow vanuatu_yyStackOverflow
#define yyRuleInfo vanuatu_yyRuleInfo
#define yyunput vanuatu_yyunput
#define yyzerominor vanuatu_yyzerominor
#define yyTraceFILE vanuatu_yyTraceFILE
#define yyTracePrompt vanuatu_yyTracePrompt
#define yyTokenName vanuatu_yyTokenName
#define yyRuleName vanuatu_yyRuleName
#define ParseTrace vanuatu_ParseTrace
#define yylex vanuatu_yylex
#define YY_DECL int yylex (yyscan_t yyscanner)
/* including LEMON generated header */
#include "vanuatuWkt.h"
typedef union
{
double dval;
struct symtab *symp;
} vanuatu_yystype;
#define YYSTYPE vanuatu_yystype
struct vanuatu_dyn_block
{
/* a struct taking trace of dynamic allocations */
int type[VANUATU_DYN_BLOCK];
void *ptr[VANUATU_DYN_BLOCK];
int index;
struct vanuatu_dyn_block *next;
};
struct vanuatu_data
{
/* a struct used to make the lexer-parser reentrant and thread-safe */
int vanuatu_parse_error;
int vanuatu_line;
int vanuatu_col;
struct vanuatu_dyn_block *vanuatu_first_dyn_block;
struct vanuatu_dyn_block *vanuatu_last_dyn_block;
gaiaGeomCollPtr result;
YYSTYPE VanuatuWktlval;
};
static struct vanuatu_dyn_block *
vanuatuCreateDynBlock (void)
{
/* allocating a new block to trace dynamic allocations */
int i;
struct vanuatu_dyn_block *p = malloc (sizeof (struct vanuatu_dyn_block));
for (i = 0; i < VANUATU_DYN_BLOCK; i++)
{
/* initializing map entries */
p->type[i] = VANUATU_DYN_NONE;
p->ptr[i] = NULL;
}
p->index = 0;
p->next = NULL;
return p;
}
static void
vanuatuMapDynAlloc (struct vanuatu_data *p_data, int type, void *ptr)
{
/* appending a dynamic allocation into the map */
struct vanuatu_dyn_block *p;
if (p_data->vanuatu_first_dyn_block == NULL)
{
/* inserting the first block of the map */
p = vanuatuCreateDynBlock ();
p_data->vanuatu_first_dyn_block = p;
p_data->vanuatu_last_dyn_block = p;
}
if (p_data->vanuatu_last_dyn_block->index >= VANUATU_DYN_BLOCK)
{
/* adding a further block to the map */
p = vanuatuCreateDynBlock ();
p_data->vanuatu_last_dyn_block->next = p;
p_data->vanuatu_last_dyn_block = p;
}
p_data->vanuatu_last_dyn_block->type[p_data->
vanuatu_last_dyn_block->index] = type;
p_data->vanuatu_last_dyn_block->ptr[p_data->vanuatu_last_dyn_block->index] =
ptr;
p_data->vanuatu_last_dyn_block->index++;
}
static void
vanuatuMapDynClean (struct vanuatu_data *p_data, void *ptr)
{
/* deleting a dynamic allocation from the map */
int i;
struct vanuatu_dyn_block *p = p_data->vanuatu_first_dyn_block;
while (p)
{
for (i = 0; i < VANUATU_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case VANUATU_DYN_POINT:
case VANUATU_DYN_LINESTRING:
case VANUATU_DYN_POLYGON:
case VANUATU_DYN_RING:
case VANUATU_DYN_GEOMETRY:
if (p->ptr[i] == ptr)
{
p->type[i] = VANUATU_DYN_NONE;
return;
}
break;
};
}
p = p->next;
}
}
static void
vanuatuCleanMapDynAlloc (struct vanuatu_data *p_data, int clean_all)
{
/* cleaning the dynamic allocations map */
int i;
struct vanuatu_dyn_block *pn;
struct vanuatu_dyn_block *p = p_data->vanuatu_first_dyn_block;
while (p)
{
if (clean_all)
{
for (i = 0; i < VANUATU_DYN_BLOCK; i++)
{
/* deleting Geometry objects */
switch (p->type[i])
{
case VANUATU_DYN_POINT:
gaiaFreePoint ((gaiaPointPtr) (p->ptr[i]));
break;
case VANUATU_DYN_LINESTRING:
gaiaFreeLinestring ((gaiaLinestringPtr)
(p->ptr[i]));
break;
case VANUATU_DYN_POLYGON:
gaiaFreePolygon ((gaiaPolygonPtr) (p->ptr[i]));
break;
case VANUATU_DYN_RING:
gaiaFreeRing ((gaiaRingPtr) (p->ptr[i]));
break;
case VANUATU_DYN_GEOMETRY:
gaiaFreeGeomColl ((gaiaGeomCollPtr) (p->ptr[i]));
break;
};
}
}
/* deleting the map block */
pn = p->next;
free (p);
p = pn;
}
}
static int
vanuatuCheckValidity (gaiaGeomCollPtr geom)
{
/* checks if this one is a degenerated geometry */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int ib;
int entities = 0;
pt = geom->FirstPoint;
while (pt)
{
/* checking points */
entities++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* checking linestrings */
if (ln->Points < 2)
return 0;
entities++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* checking polygons */
rng = pg->Exterior;
if (rng->Points < 4)
return 0;
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
if (rng->Points < 4)
return 0;
}
entities++;
pg = pg->Next;
}
if (!entities)
return 0;
return 1;
}
static gaiaGeomCollPtr
gaiaGeometryFromPoint (struct vanuatu_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINT */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomColl ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINT;
gaiaAddPointToGeomColl (geom, point->X, point->Y);
vanuatuMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromPointZ (struct vanuatu_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTZ */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZ ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZ;
gaiaAddPointToGeomCollXYZ (geom, point->X, point->Y, point->Z);
vanuatuMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromPointM (struct vanuatu_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTM */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTM;
gaiaAddPointToGeomCollXYM (geom, point->X, point->Y, point->M);
vanuatuMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromPointZM (struct vanuatu_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTZM */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZM;
gaiaAddPointToGeomCollXYZM (geom, point->X, point->Y, point->Z, point->M);
vanuatuMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromLinestring (struct vanuatu_data *p_data, gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRING */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
geom = gaiaAllocGeomColl ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPoint (line->Coords, iv, &x, &y);
gaiaSetPoint (line2->Coords, iv, x, y);
}
vanuatuMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromLinestringZ (struct vanuatu_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGZ */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
geom = gaiaAllocGeomCollXYZ ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
vanuatuMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromLinestringM (struct vanuatu_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGM */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double m;
geom = gaiaAllocGeomCollXYM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (line2->Coords, iv, x, y, m);
}
vanuatuMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaGeometryFromLinestringZM (struct vanuatu_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGZM */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
double m;
geom = gaiaAllocGeomCollXYZM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (line2->Coords, iv, x, y, z, m);
}
vanuatuMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
/******************************************************************************
** The following code was created by Team Vanuatu of The University of Toronto.
** It is responsible for handling the parsing of wkt expressions. The parser
** is built using LEMON and the cooresponding methods were written by the
** students.
Authors:
Ruppi Rana ruppi.rana@gmail.com
Dev Tanna dev.tanna@gmail.com
Elias Adum elias.adum@gmail.com
Benton Hui benton.hui@gmail.com
Abhayan Sundararajan abhayan@gmail.com
Chee-Lun Michael Stephen Cho cheelun.cho@gmail.com
Nikola Banovic nikola.banovic@gmail.com
Yong Jian yong.jian@utoronto.ca
Supervisor:
Greg Wilson gvwilson@cs.toronto.ca
-------------------------------------------------------------------------------
*/
/*
* Creates a 2D (xy) point in SpatiaLite
* x and y are pointers to doubles which represent the x and y coordinates of the point to be created.
* Returns a gaiaPointPtr representing the created point.
*
* Creates a 2D (xy) point. This is a parser helper function which is called when 2D coordinates are encountered.
* Parameters x and y are pointers to doubles which represent the x and y coordinates of the point to be created.
* Returns a gaiaPointPtr pointing to the created 2D point.
*/
static gaiaPointPtr
vanuatu_point_xy (struct vanuatu_data *p_data, double *x, double *y)
{
gaiaPointPtr pt = gaiaAllocPoint (*x, *y);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_POINT, pt);
return pt;
}
/*
* Creates a 3D (xyz) point in SpatiaLite
* x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr representing the created point.
*
* Creates a 3D (xyz) point. This is a parser helper function which is called when 3D coordinates are encountered.
* Parameters x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr pointing to the 3D created point.
*/
static gaiaPointPtr
vanuatu_point_xyz (struct vanuatu_data *p_data, double *x, double *y, double *z)
{
gaiaPointPtr pt = gaiaAllocPointXYZ (*x, *y, *z);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_POINT, pt);
return pt;
}
/*
* Creates a 2D (xy) point with an m value which is a part of the linear reference system. This is a parser helper
* function which is called when 2D *coordinates with an m value are encountered.
* Parameters x and y are pointers to doubles which represent the x and y coordinates of the point to be created.
* Parameter m is a pointer to a double which represents the part of the linear reference system.
* Returns a gaiaPointPtr pointing to the created 2D point with an m value.
*/
static gaiaPointPtr
vanuatu_point_xym (struct vanuatu_data *p_data, double *x, double *y, double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYM (*x, *y, *m);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_POINT, pt);
return pt;
}
/*
* Creates a 4D (xyz) point with an m value which is a part of the linear reference system. This is a parser helper
* function which is called when *4Dcoordinates with an m value are encountered
* Parameters x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Parameter m is a pointer to a double which represents the part of the linear reference system.
* Returns a gaiaPointPtr pointing the created 4D point with an m value.
*/
gaiaPointPtr
vanuatu_point_xyzm (struct vanuatu_data *p_data, double *x, double *y,
double *z, double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYZM (*x, *y, *z, *m);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_POINT, pt);
return pt;
}
/*
* Builds a geometry collection from a point. The geometry collection should contain only one element ? the point.
* The correct geometry type must be *decided based on the point type. The parser should call this function when the
* ?POINT? WKT expression is encountered.
* Parameter point is a pointer to a 2D, 3D, 2D with an m value, or 4D with an m value point.
* Returns a geometry collection containing the point. The geometry must have FirstPoint and LastPoint pointing to the
* same place as point. *DimensionModel must be the same as the model of the point and DimensionType must be GAIA_TYPE_POINT.
*/
static gaiaGeomCollPtr
vanuatu_buildGeomFromPoint (struct vanuatu_data *p_data, gaiaPointPtr point)
{
switch (point->DimensionModel)
{
case GAIA_XY:
return gaiaGeometryFromPoint (p_data, point);
case GAIA_XY_Z:
return gaiaGeometryFromPointZ (p_data, point);
case GAIA_XY_M:
return gaiaGeometryFromPointM (p_data, point);
case GAIA_XY_Z_M:
return gaiaGeometryFromPointZM (p_data, point);
}
return NULL;
}
/*
* Creates a 2D (xy) linestring from a list of 2D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 2D (xy) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
vanuatu_linestring_xy (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestring (points);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPoint (linestring->Coords, i, p->X, p->Y);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 3D (xyz) linestring from a list of 3D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 3D (xyz) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
vanuatu_linestring_xyz (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZ (points);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZ (linestring->Coords, i, p->X, p->Y, p->Z);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 2D (xy) with m value linestring from a list of 2D with m value points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 2D (xy) with m value points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
vanuatu_linestring_xym (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYM (points);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYM (linestring->Coords, i, p->X, p->Y, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 4D (xyz) with m value linestring from a list of 4D with m value points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 4D (xyz) with m value points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
vanuatu_linestring_xyzm (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZM (points);
vanuatuMapDynAlloc (p_data, VANUATU_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZM (linestring->Coords, i, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Builds a geometry collection from a linestring.
*/
static gaiaGeomCollPtr
vanuatu_buildGeomFromLinestring (struct vanuatu_data *p_data,
gaiaLinestringPtr line)
{
switch (line->DimensionModel)
{
case GAIA_XY:
return gaiaGeometryFromLinestring (p_data, line);
case GAIA_XY_Z:
return gaiaGeometryFromLinestringZ (p_data, line);
case GAIA_XY_M:
return gaiaGeometryFromLinestringM (p_data, line);
case GAIA_XY_Z_M:
return gaiaGeometryFromLinestringZM (p_data, line);
}
return NULL;
}
/*
* Helper function that determines the number of points in the linked list.
*/
static int
vanuatu_count_points (gaiaPointPtr first)
{
/* Counts the number of points in the ring. */
gaiaPointPtr p = first;
int numpoints = 0;
while (p != NULL)
{
numpoints++;
p = p->Next;
}
return numpoints;
}
/*
* Creates a 2D (xy) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 2D (xy) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
vanuatu_ring_xy (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = vanuatu_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRing (numpoints);
if (ring == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPoint (ring->Coords, index, p->X, p->Y);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 3D (xyz) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 3D (xyz) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
vanuatu_ring_xyz (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = vanuatu_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYZ (numpoints);
if (ring == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZ (ring->Coords, index, p->X, p->Y, p->Z);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 2D (xym) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 2D (xym) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
vanuatu_ring_xym (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = vanuatu_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYM (numpoints);
if (ring == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYM (ring->Coords, index, p->X, p->Y, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 3D (xyzm) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 3D (xyzm) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
vanuatu_ring_xyzm (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = vanuatu_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYZM (numpoints);
if (ring == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZM (ring->Coords, index, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Helper function that will create any type of polygon (xy, xym, xyz, xyzm) in SpatiaLite.
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are of the same type. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
vanuatu_polygon_any_type (struct vanuatu_data *p_data, gaiaRingPtr first)
{
gaiaRingPtr p;
gaiaRingPtr p_n;
gaiaPolygonPtr polygon;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a polygon structure with the exterior ring. */
polygon = gaiaCreatePolygon (first);
if (polygon == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_POLYGON, polygon);
/* Adds all interior rings into the polygon structure. */
p = first;
while (p != NULL)
{
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
if (p == first)
gaiaFreeRing (p);
else
gaiaAddRingToPolyg (polygon, p);
p = p_n;
}
return polygon;
}
/*
* Creates a 2D (xy) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 2D (xy) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
vanuatu_polygon_xy (struct vanuatu_data *p_data, gaiaRingPtr first)
{
return vanuatu_polygon_any_type (p_data, first);
}
/*
* Creates a 3D (xyz) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 3D (xyz) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
vanuatu_polygon_xyz (struct vanuatu_data *p_data, gaiaRingPtr first)
{
return vanuatu_polygon_any_type (p_data, first);
}
/*
* Creates a 2D (xym) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 2D (xym) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
vanuatu_polygon_xym (struct vanuatu_data *p_data, gaiaRingPtr first)
{
return vanuatu_polygon_any_type (p_data, first);
}
/*
* Creates a 3D (xyzm) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 3D (xyzm) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
vanuatu_polygon_xyzm (struct vanuatu_data *p_data, gaiaRingPtr first)
{
return vanuatu_polygon_any_type (p_data, first);
}
/*
* Builds a geometry collection from a polygon.
* NOTE: This function may already be implemented in the SpatiaLite code base. If it is, make sure that we
* can use it (ie. it doesn't use any other variables or anything else set by Sandro's parser). If you find
* that we can use an existing function then ignore this one.
*/
static gaiaGeomCollPtr
vanuatu_buildGeomFromPolygon (struct vanuatu_data *p_data,
gaiaPolygonPtr polygon)
{
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (polygon == NULL)
{
return NULL;
}
/* Creates and allocates a geometry collection containing a multipoint. */
switch (polygon->DimensionModel)
{
case GAIA_XY:
geom = gaiaAllocGeomColl ();
break;
case GAIA_XY_Z:
geom = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
geom = gaiaAllocGeomCollXYM ();
break;
case GAIA_XY_Z_M:
geom = gaiaAllocGeomCollXYZM ();
break;
}
if (geom == NULL)
{
return NULL;
}
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POLYGON;
/* Stores the location of the first and last polygons in the linked list. */
geom->FirstPolygon = polygon;
while (polygon != NULL)
{
vanuatuMapDynClean (p_data, polygon);
geom->LastPolygon = polygon;
polygon = polygon->Next;
}
return geom;
}
/*
* Creates a 2D (xy) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 2D (xy) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
vanuatu_multipoint_xy (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 2D (xy) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomColl (geom, p->X, p->Y);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 3D (xyz) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 3D (xyz) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
vanuatu_multipoint_xyz (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYZ ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 3D (xyz) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYZ (geom, p->X, p->Y, p->Z);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 2D (xym) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 2D (xym) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
vanuatu_multipoint_xym (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYM ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 2D (xym) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYM (geom, p->X, p->Y, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 3D (xyzm) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points given to the function are 3D (xyzm) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
vanuatu_multipoint_xyzm (struct vanuatu_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYZM ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 3D (xyzm) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYZM (geom, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 2D (xy) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 2D (xy) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 2D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XY and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
vanuatu_multilinestring_xy (struct vanuatu_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomColl ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Returns a geometry collection containing the created multilinestring object (?).
* Creates a geometry collection containing 3D (xyz) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 3D (xyz) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 3D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the *list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XYZ and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
vanuatu_multilinestring_xyz (struct vanuatu_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZ ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 2D (xy) with m value linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 2D (xy) with m value linestrings. There must be at least 1 linestring
* in the list.
* Returns a pointer to the created geometry collection of 2D with m value linestrings. The geometry must have FirstLinestring
* pointing to the first *linestring in the list pointed by first and LastLinestring pointing to the last element of the same list.
* DimensionModel must be GAIA_XYM and *DimensionType must be GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
vanuatu_multilinestring_xym (struct vanuatu_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 4D (xyz) with m value linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 4D (xyz) with m value linestrings. There must be at least 1 linestring
* in the list.
* Returns a pointer to the created geometry collection of 4D with m value linestrings. The geometry must have FirstLinestring
* pointing to the first *linestring in the list pointed by first and LastLinestring pointing to the last element of the same list.
* DimensionModel must be GAIA_XYZM and *DimensionType must be GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
vanuatu_multilinestring_xyzm (struct vanuatu_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 2D (xy) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should
* be added to the collection. All of the polygons in the list must be 2D (xy) polygons. There must be
* at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 2D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing
* to the last element of the same list. DimensionModel must be GAIA_XY and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
vanuatu_multipolygon_xy (struct vanuatu_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 3D (xyz) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should be
* added to the collection. All of the polygons in the list must be 3D (xyz) polygons. There must be at
* least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 3D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing to
* the last element of the same list. DimensionModel must be GAIA_XYZ and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
vanuatu_multipolygon_xyz (struct vanuatu_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZ ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 2D (xy) with m value polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should
* be added to the collection. All of the polygons in the list must be 2D (xy) with m value polygons.
* There must be at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 2D with m value polygons. The geometry
* must have FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon
* pointing to the last element of the same list. DimensionModel must be GAIA_XYM and DimensionType
* must be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
vanuatu_multipolygon_xym (struct vanuatu_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 4D (xyz) with m value polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should be
* added to the collection. All of the polygons in the list must be 4D (xyz) with m value polygons.
* There must be at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 4D with m value polygons. The geometry must
* have FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing
// * to the last element of the same list. DimensionModel must be GAIA_XYZM and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
vanuatu_multipolygon_xyzm (struct vanuatu_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZM ();
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
vanuatuMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static void
vanuatu_geomColl_common (struct vanuatu_data *p_data, gaiaGeomCollPtr org,
gaiaGeomCollPtr dst)
{
/*
/ helper function: xfers entities between the Origin and Destination
/ Sandro Furieri: 2010 October 12
*/
gaiaGeomCollPtr p = org;
gaiaGeomCollPtr p_n;
gaiaPointPtr pt;
gaiaPointPtr pt_n;
gaiaLinestringPtr ln;
gaiaLinestringPtr ln_n;
gaiaPolygonPtr pg;
gaiaPolygonPtr pg_n;
while (p)
{
pt = p->FirstPoint;
while (pt)
{
pt_n = pt->Next;
pt->Next = NULL;
if (dst->FirstPoint == NULL)
dst->FirstPoint = pt;
if (dst->LastPoint != NULL)
dst->LastPoint->Next = pt;
dst->LastPoint = pt;
pt = pt_n;
}
ln = p->FirstLinestring;
while (ln)
{
ln_n = ln->Next;
ln->Next = NULL;
if (dst->FirstLinestring == NULL)
dst->FirstLinestring = ln;
if (dst->LastLinestring != NULL)
dst->LastLinestring->Next = ln;
dst->LastLinestring = ln;
ln = ln_n;
}
pg = p->FirstPolygon;
while (pg)
{
pg_n = pg->Next;
pg->Next = NULL;
if (dst->FirstPolygon == NULL)
dst->FirstPolygon = pg;
if (dst->LastPolygon != NULL)
dst->LastPolygon->Next = pg;
dst->LastPolygon = pg;
pg = pg_n;
}
p_n = p->Next;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
vanuatuMapDynClean (p_data, p);
gaiaFreeGeomColl (p);
p = p_n;
}
}
/* Creates a 2D (xy) geometry collection in SpatiaLite
*
* first is the first geometry collection in a linked list of geometry collections.
* Each geometry collection represents a single type of object (eg. one could be a POINT,
* another could be a LINESTRING, another could be a MULTILINESTRING, etc.).
*
* The type of object represented by any geometry collection is stored in the declaredType
* field of its struct. For example, if first->declaredType = GAIA_POINT, then first represents a point.
* If first->declaredType = GAIA_MULTIPOINT, then first represents a multipoint.
*
* NOTE: geometry collections cannot contain other geometry collections (have to confirm this
* with Sandro).
*
* The goal of this function is to take the information from all of the structs in the linked list and
* return one geomColl struct containing all of that information.
*
* The integers used for 'declaredType' are defined in gaiageo.h. In this function, the only values
* contained in 'declaredType' that will be encountered will be:
*
* GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON,
* GAIA_MULTIPOINT, GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON
*/
static gaiaGeomCollPtr
vanuatu_geomColl_xy (struct vanuatu_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY;
vanuatu_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTZ, GAIA_LINESTRINGZ, GAIA_POLYGONZ,
* GAIA_MULTIPOINTZ, GAIA_MULTILINESTRINGZ, GAIA_MULTIPOLYGONZ
*/
static gaiaGeomCollPtr
vanuatu_geomColl_xyz (struct vanuatu_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z;
vanuatu_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTM, GAIA_LINESTRINGM, GAIA_POLYGONM,
* GAIA_MULTIPOINTM, GAIA_MULTILINESTRINGM, GAIA_MULTIPOLYGONM
*/
static gaiaGeomCollPtr
vanuatu_geomColl_xym (struct vanuatu_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_M;
vanuatu_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTZM, GAIA_LINESTRINGZM, GAIA_POLYGONZM,
* GAIA_MULTIPOINTZM, GAIA_MULTILINESTRINGZM, GAIA_MULTIPOLYGONZM
*/
static gaiaGeomCollPtr
vanuatu_geomColl_xyzm (struct vanuatu_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
vanuatuMapDynAlloc (p_data, VANUATU_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z_M;
vanuatu_geomColl_common (p_data, first, geom);
return geom;
}
/* including LEMON generated code */
#include "vanuatuWkt.c"
/*
** CAVEAT: there is an incompatibility between LEMON and FLEX
** this macro resolves the issue
*/
#undef yy_accept
#define yy_accept yy_vanuatu_flex_accept
/* including FLEX generated code */
#include "lex.VanuatuWkt.c"
/*
** This is a linked-list struct to store all the values for each token.
** All tokens will have a value of 0, except tokens denoted as NUM.
** NUM tokens are geometry coordinates and will contain the floating
** point number.
*/
typedef struct vanuatuFlexTokenStruct
{
double value;
struct vanuatuFlexTokenStruct *Next;
} vanuatuFlexToken;
/*
** Function to clean up the linked-list of token values.
*/
static int
vanuatu_cleanup (vanuatuFlexToken * token)
{
vanuatuFlexToken *ptok;
vanuatuFlexToken *ptok_n;
if (token == NULL)
return 0;
ptok = token;
while (ptok)
{
ptok_n = ptok->Next;
free (ptok);
ptok = ptok_n;
}
return 0;
}
gaiaGeomCollPtr
gaiaParseWkt (const unsigned char *dirty_buffer, short type)
{
void *pParser = ParseAlloc (malloc);
/* Linked-list of token values */
vanuatuFlexToken *tokens = malloc (sizeof (vanuatuFlexToken));
/* Pointer to the head of the list */
vanuatuFlexToken *head = tokens;
int yv;
yyscan_t scanner;
struct vanuatu_data str_data;
/* initializing the helper structs */
str_data.vanuatu_line = 1;
str_data.vanuatu_col = 1;
str_data.vanuatu_parse_error = 0;
str_data.vanuatu_first_dyn_block = NULL;
str_data.vanuatu_last_dyn_block = NULL;
str_data.result = NULL;
/* initializing the scanner state */
VanuatuWktlex_init_extra (&str_data, &scanner);
tokens->Next = NULL;
VanuatuWkt_scan_string ((char *) dirty_buffer, scanner);
/*
/ Keep tokenizing until we reach the end
/ yylex() will return the next matching Token for us.
*/
while ((yv = yylex (scanner)) != 0)
{
if (yv == -1)
{
str_data.vanuatu_parse_error = 1;
break;
}
tokens->Next = malloc (sizeof (vanuatuFlexToken));
tokens->Next->Next = NULL;
tokens->Next->value = str_data.VanuatuWktlval.dval;
/* Pass the token to the wkt parser created from lemon */
Parse (pParser, yv, &(tokens->Next->value), &str_data);
tokens = tokens->Next;
}
/* This denotes the end of a line as well as the end of the parser */
Parse (pParser, VANUATU_NEWLINE, 0, &str_data);
ParseFree (pParser, free);
VanuatuWktlex_destroy (scanner);
/* Assigning the token as the end to avoid seg faults while cleaning */
tokens->Next = NULL;
vanuatu_cleanup (head);
/*
** Sandro Furieri 2010 Apr 4
** checking if any parsing error was encountered
*/
if (str_data.vanuatu_parse_error)
{
if (str_data.result != NULL)
{
/* if a Geometry-result has been produced, the stack is already cleaned */
gaiaFreeGeomColl (str_data.result);
vanuatuCleanMapDynAlloc (&str_data, 0);
}
else
{
/* otherwise we are required to clean the stack */
vanuatuCleanMapDynAlloc (&str_data, 1);
}
return NULL;
}
vanuatuCleanMapDynAlloc (&str_data, 0);
/*
** Sandro Furieri 2010 Apr 4
** final checkup for validity
*/
if (str_data.result == NULL)
return NULL;
if (!vanuatuCheckValidity (str_data.result))
{
gaiaFreeGeomColl (str_data.result);
return NULL;
}
if (type < 0)
; /* no restrinction about GEOMETRY CLASS TYPE */
else
{
if (str_data.result->DeclaredType != type)
{
/* invalid CLASS TYPE for request */
gaiaFreeGeomColl (str_data.result);
return NULL;
}
}
gaiaMbrGeometry (str_data.result);
return str_data.result;
}
/******************************************************************************
** This is the end of the code that was created by Team Vanuatu
** of The University of Toronto.
Authors:
Ruppi Rana ruppi.rana@gmail.com
Dev Tanna dev.tanna@gmail.com
Elias Adum elias.adum@gmail.com
Benton Hui benton.hui@gmail.com
Abhayan Sundararajan abhayan@gmail.com
Chee-Lun Michael Stephen Cho cheelun.cho@gmail.com
Nikola Banovic nikola.banovic@gmail.com
Yong Jian yong.jian@utoronto.ca
Supervisor:
Greg Wilson gvwilson@cs.toronto.ca
-------------------------------------------------------------------------------
*/
/*
** CAVEAT: we must now undefine any Lemon/Flex own macro
*/
#undef YYNOCODE
#undef YYNSTATE
#undef YYNRULE
#undef YY_SHIFT_MAX
#undef YY_SHIFT_USE_DFLT
#undef YY_REDUCE_USE_DFLT
#undef YY_REDUCE_MAX
#undef YY_FLUSH_BUFFER
#undef YY_DO_BEFORE_ACTION
#undef YY_NUM_RULES
#undef YY_END_OF_BUFFER
#undef YY_END_FILE
#undef YYACTIONTYPE
#undef YY_SZ_ACTTAB
#undef YY_NEW_FILE
#undef BEGIN
#undef YY_START
#undef YY_CURRENT_BUFFER
#undef YY_CURRENT_BUFFER_LVALUE
#undef YY_STATE_BUF_SIZE
#undef YY_DECL
#undef YY_FATAL_ERROR
#undef YYMINORTYPE
#undef YY_CHAR
#undef YYSTYPE
#undef input
#undef ParseAlloc
#undef ParseFree
#undef ParseStackPeak
#undef Parse
#undef yyalloc
#undef yyfree
#undef yyin
#undef yyleng
#undef yyless
#undef yylex
#undef yylineno
#undef yyout
#undef yyrealloc
#undef yyrestart
#undef yyStackEntry
#undef yytext
#undef yywrap
#undef yyzerominor
#undef yy_accept
#undef yy_action
#undef yy_base
#undef yy_buffer_stack
#undef yy_buffer_stack_max
#undef yy_buffer_stack_top
#undef yy_c_buf_p
#undef yy_chk
#undef yy_create_buffer
#undef yy_def
#undef yy_default
#undef yy_delete_buffer
#undef yy_destructor
#undef yy_ec
#undef yy_fatal_error
#undef yy_find_reduce_action
#undef yy_find_shift_action
#undef yy_flex_debug
#undef yy_flush_buffer
#undef yy_get_next_buffer
#undef yy_get_previous_state
#undef yy_init
#undef yy_init_buffer
#undef yy_init_globals
#undef yy_load_buffer
#undef yy_load_buffer_state
#undef yy_lookahead
#undef yy_meta
#undef yy_new_buffer
#undef yy_nxt
#undef yy_parse_failed
#undef yy_pop_parser_stack
#undef yy_reduce
#undef yy_reduce_ofst
#undef yy_set_bol
#undef yy_set_interactive
#undef yy_shift
#undef yy_shift_ofst
#undef yy_start
#undef yy_state_type
#undef yy_switch_to_buffer
#undef yy_syntax_error
#undef yy_trans_info
#undef yy_try_NUL_trans
#undef yyParser
#undef yyStackEntry
#undef yyStackOverflow
#undef yyRuleInfo
#undef yytext_ptr
#undef yyunput
#undef yyzerominor
#undef ParseARG_SDECL
#undef ParseARG_PDECL
#undef ParseARG_FETCH
#undef ParseARG_STORE
#undef REJECT
#undef yymore
#undef YY_MORE_ADJ
#undef YY_RESTORE_YY_MORE_OFFSET
#undef YY_LESS_LINENO
#undef yyTracePrompt
#undef yyTraceFILE
#undef yyTokenName
#undef yyRuleName
#undef ParseTrace
#undef yylex
#undef YY_DECL
libspatialite-5.1.0/src/gaiageo/gg_ewkt.c 0000644 0001750 0001750 00000165005 14463127014 015253 0000000 0000000 /*
gg_ewkt.c -- EWKT parser/lexer
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2011-2023
the Initial Developer. All Rights Reserved.
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define atoll _atoi64
#endif /* not WIN32 */
#if defined(_WIN32) || defined(WIN32)
#include
#ifndef isatty
#define isatty _isatty
#endif
#ifndef fileno
#define fileno _fileno
#endif
#endif
#define EWKT_DYN_NONE 0
#define EWKT_DYN_POINT 1
#define EWKT_DYN_LINESTRING 2
#define EWKT_DYN_POLYGON 3
#define EWKT_DYN_RING 4
#define EWKT_DYN_GEOMETRY 5
#define EWKT_DYN_BLOCK 1024
/*
** CAVEAT: we must redefine any Lemon/Flex own macro
*/
#define YYMINORTYPE EWKT_MINORTYPE
#define YY_CHAR EWKT_YY_CHAR
#define input ewkt_input
#define ParseAlloc ewktParseAlloc
#define ParseFree ewktParseFree
#define ParseStackPeak ewktParseStackPeak
#define Parse ewktParse
#define yyStackEntry ewkt_yyStackEntry
#define yyzerominor ewkt_yyzerominor
#define yy_accept ewkt_yy_accept
#define yy_action ewkt_yy_action
#define yy_base ewkt_yy_base
#define yy_buffer_stack ewkt_yy_buffer_stack
#define yy_buffer_stack_max ewkt_yy_buffer_stack_max
#define yy_buffer_stack_top ewkt_yy_buffer_stack_top
#define yy_c_buf_p ewkt_yy_c_buf_p
#define yy_chk ewkt_yy_chk
#define yy_def ewkt_yy_def
#define yy_default ewkt_yy_default
#define yy_destructor ewkt_yy_destructor
#define yy_ec ewkt_yy_ec
#define yy_fatal_error ewkt_yy_fatal_error
#define yy_find_reduce_action ewkt_yy_find_reduce_action
#define yy_find_shift_action ewkt_yy_find_shift_action
#define yy_get_next_buffer ewkt_yy_get_next_buffer
#define yy_get_previous_state ewkt_yy_get_previous_state
#define yy_init ewkt_yy_init
#define yy_init_globals ewkt_yy_init_globals
#define yy_lookahead ewkt_yy_lookahead
#define yy_meta ewkt_yy_meta
#define yy_nxt ewkt_yy_nxt
#define yy_parse_failed ewkt_yy_parse_failed
#define yy_pop_parser_stack ewkt_yy_pop_parser_stack
#define yy_reduce ewkt_yy_reduce
#define yy_reduce_ofst ewkt_yy_reduce_ofst
#define yy_shift ewkt_yy_shift
#define yy_shift_ofst ewkt_yy_shift_ofst
#define yy_start ewkt_yy_start
#define yy_state_type ewkt_yy_state_type
#define yy_syntax_error ewkt_yy_syntax_error
#define yy_trans_info ewkt_yy_trans_info
#define yy_try_NUL_trans ewkt_yy_try_NUL_trans
#define yyParser ewkt_yyParser
#define yyStackEntry ewkt_yyStackEntry
#define yyStackOverflow ewkt_yyStackOverflow
#define yyRuleInfo ewkt_yyRuleInfo
#define yyunput ewkt_yyunput
#define yyzerominor ewkt_yyzerominor
#define yyTraceFILE ewkt_yyTraceFILE
#define yyTracePrompt ewkt_yyTracePrompt
#define yyTokenName ewkt_yyTokenName
#define yyRuleName ewkt_yyRuleName
#define ParseTrace ewkt_ParseTrace
#define yylex ewky_yylex
#define YY_DECL int yylex (yyscan_t yyscanner)
/* including LEMON generated header */
#include "Ewkt.h"
typedef union
{
double dval;
struct symtab *symp;
} ewkt_yystype;
#define YYSTYPE ewkt_yystype
struct ewkt_dyn_block
{
/* a struct taking trace of dynamic allocations */
int type[EWKT_DYN_BLOCK];
void *ptr[EWKT_DYN_BLOCK];
int index;
struct ewkt_dyn_block *next;
};
struct ewkt_data
{
/* a struct used to make the lexer-parser reentrant and thread-safe */
int ewkt_parse_error;
int ewkt_line;
int ewkt_col;
struct ewkt_dyn_block *ewkt_first_dyn_block;
struct ewkt_dyn_block *ewkt_last_dyn_block;
gaiaGeomCollPtr result;
YYSTYPE EwktLval;
};
static struct ewkt_dyn_block *
ewktCreateDynBlock (void)
{
/* allocating a new block to trace dynamic allocations */
int i;
struct ewkt_dyn_block *p = malloc (sizeof (struct ewkt_dyn_block));
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
/* initializing map entries */
p->type[i] = EWKT_DYN_NONE;
p->ptr[i] = NULL;
}
p->index = 0;
p->next = NULL;
return p;
}
static void
ewktMapDynAlloc (struct ewkt_data *p_data, int type, void *ptr)
{
/* appending a dynamic allocation into the map */
struct ewkt_dyn_block *p;
if (p_data->ewkt_first_dyn_block == NULL)
{
/* inserting the first block of the map */
p = ewktCreateDynBlock ();
p_data->ewkt_first_dyn_block = p;
p_data->ewkt_last_dyn_block = p;
}
if (p_data->ewkt_last_dyn_block->index >= EWKT_DYN_BLOCK)
{
/* adding a further block to the map */
p = ewktCreateDynBlock ();
p_data->ewkt_last_dyn_block->next = p;
p_data->ewkt_last_dyn_block = p;
}
p_data->ewkt_last_dyn_block->type[p_data->ewkt_last_dyn_block->index] =
type;
p_data->ewkt_last_dyn_block->ptr[p_data->ewkt_last_dyn_block->index] = ptr;
p_data->ewkt_last_dyn_block->index++;
}
static void
ewktMapDynClean (struct ewkt_data *p_data, void *ptr)
{
/* deleting a dynamic allocation from the map */
int i;
struct ewkt_dyn_block *p = p_data->ewkt_first_dyn_block;
while (p)
{
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case EWKT_DYN_POINT:
case EWKT_DYN_LINESTRING:
case EWKT_DYN_POLYGON:
case EWKT_DYN_RING:
case EWKT_DYN_GEOMETRY:
if (p->ptr[i] == ptr)
{
p->type[i] = EWKT_DYN_NONE;
return;
}
break;
};
}
p = p->next;
}
}
static void
ewktCleanMapDynAlloc (struct ewkt_data *p_data, int clean_all)
{
/* cleaning the dynamic allocations map */
int i;
struct ewkt_dyn_block *pn;
struct ewkt_dyn_block *p = p_data->ewkt_first_dyn_block;
while (p)
{
if (clean_all)
{
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
/* deleting Geometry objects */
switch (p->type[i])
{
case EWKT_DYN_POINT:
gaiaFreePoint ((gaiaPointPtr) (p->ptr[i]));
break;
case EWKT_DYN_LINESTRING:
gaiaFreeLinestring ((gaiaLinestringPtr)
(p->ptr[i]));
break;
case EWKT_DYN_POLYGON:
gaiaFreePolygon ((gaiaPolygonPtr) (p->ptr[i]));
break;
case EWKT_DYN_RING:
gaiaFreeRing ((gaiaRingPtr) (p->ptr[i]));
break;
case EWKT_DYN_GEOMETRY:
gaiaFreeGeomColl ((gaiaGeomCollPtr) (p->ptr[i]));
break;
};
}
}
/* deleting the map block */
pn = p->next;
free (p);
p = pn;
}
}
static int
ewktCheckValidity (gaiaGeomCollPtr geom)
{
/* checks if this one is a degenerated geometry */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int ib;
int entities = 0;
pt = geom->FirstPoint;
while (pt)
{
/* checking points */
entities++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* checking linestrings */
if (ln->Points < 2)
return 0;
entities++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* checking polygons */
rng = pg->Exterior;
if (rng->Points < 4)
return 0;
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
if (rng->Points < 4)
return 0;
}
entities++;
pg = pg->Next;
}
if (!entities)
return 0;
return 1;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPoint (struct ewkt_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINT */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINT;
gaiaAddPointToGeomColl (geom, point->X, point->Y);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointZ (struct ewkt_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTZ */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZ;
gaiaAddPointToGeomCollXYZ (geom, point->X, point->Y, point->Z);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointM (struct ewkt_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTM */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTM;
gaiaAddPointToGeomCollXYM (geom, point->X, point->Y, point->M);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointZM (struct ewkt_data *p_data, gaiaPointPtr point)
{
/* builds a GEOMETRY containing a POINTZM */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZM;
gaiaAddPointToGeomCollXYZM (geom, point->X, point->Y, point->Z, point->M);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestring (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRING */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPoint (line->Coords, iv, &x, &y);
gaiaSetPoint (line2->Coords, iv, x, y);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringZ (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGZ */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringM (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGM */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double m;
geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (line2->Coords, iv, x, y, m);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringZM (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
/* builds a GEOMETRY containing a LINESTRINGZM */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
double m;
geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (line2->Coords, iv, x, y, z, m);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaPointPtr
ewkt_point_xy (struct ewkt_data *p_data, double *x, double *y)
{
gaiaPointPtr pt = gaiaAllocPoint (*x, *y);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
/*
* Creates a 3D (xyz) point in SpatiaLite
* x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr representing the created point.
*
* Creates a 3D (xyz) point. This is a parser helper function which is called when 3D coordinates are encountered.
* Parameters x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr pointing to the 3D created point.
*/
static gaiaPointPtr
ewkt_point_xyz (struct ewkt_data *p_data, double *x, double *y, double *z)
{
gaiaPointPtr pt = gaiaAllocPointXYZ (*x, *y, *z);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
/*
* Creates a 2D (xy) point with an m value which is a part of the linear reference system. This is a parser helper
* function which is called when 2D *coordinates with an m value are encountered.
* Parameters x and y are pointers to doubles which represent the x and y coordinates of the point to be created.
* Parameter m is a pointer to a double which represents the part of the linear reference system.
* Returns a gaiaPointPtr pointing to the created 2D point with an m value.
*/
static gaiaPointPtr
ewkt_point_xym (struct ewkt_data *p_data, double *x, double *y, double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYM (*x, *y, *m);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
/*
* Creates a 4D (xyz) point with an m value which is a part of the linear reference system. This is a parser helper
* function which is called when *4Dcoordinates with an m value are encountered
* Parameters x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Parameter m is a pointer to a double which represents the part of the linear reference system.
* Returns a gaiaPointPtr pointing the created 4D point with an m value.
*/
gaiaPointPtr
ewkt_point_xyzm (struct ewkt_data *p_data, double *x, double *y, double *z,
double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYZM (*x, *y, *z, *m);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
/*
* Builds a geometry collection from a point. The geometry collection should contain only one element ? the point.
* The correct geometry type must be *decided based on the point type. The parser should call this function when the
* ?POINT? WKT expression is encountered.
* Parameter point is a pointer to a 2D, 3D, 2D with an m value, or 4D with an m value point.
* Returns a geometry collection containing the point. The geometry must have FirstPoint and LastPoint pointing to the
* same place as point. *DimensionModel must be the same as the model of the point and DimensionType must be GAIA_TYPE_POINT.
*/
static gaiaGeomCollPtr
ewkt_buildGeomFromPoint (struct ewkt_data *p_data, gaiaPointPtr point)
{
switch (point->DimensionModel)
{
case GAIA_XY:
return gaiaEwktGeometryFromPoint (p_data, point);
case GAIA_XY_Z:
return gaiaEwktGeometryFromPointZ (p_data, point);
case GAIA_XY_M:
return gaiaEwktGeometryFromPointM (p_data, point);
case GAIA_XY_Z_M:
return gaiaEwktGeometryFromPointZM (p_data, point);
}
return NULL;
}
/*
* Creates a 2D (xy) linestring from a list of 2D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 2D (xy) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
ewkt_linestring_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestring (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPoint (linestring->Coords, i, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 3D (xyz) linestring from a list of 3D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 3D (xyz) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
ewkt_linestring_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZ (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZ (linestring->Coords, i, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 2D (xy) with m value linestring from a list of 2D with m value points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 2D (xy) with m value points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
ewkt_linestring_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYM (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYM (linestring->Coords, i, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 4D (xyz) with m value linestring from a list of 4D with m value points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 4D (xyz) with m value points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
ewkt_linestring_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZM (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZM (linestring->Coords, i, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Builds a geometry collection from a linestring.
*/
static gaiaGeomCollPtr
ewkt_buildGeomFromLinestring (struct ewkt_data *p_data, gaiaLinestringPtr line)
{
switch (line->DimensionModel)
{
case GAIA_XY:
return gaiaEwktGeometryFromLinestring (p_data, line);
case GAIA_XY_Z:
return gaiaEwktGeometryFromLinestringZ (p_data, line);
case GAIA_XY_M:
return gaiaEwktGeometryFromLinestringM (p_data, line);
case GAIA_XY_Z_M:
return gaiaEwktGeometryFromLinestringZM (p_data, line);
}
return NULL;
}
/*
* Helper function that determines the number of points in the linked list.
*/
static int
ewkt_count_points (gaiaPointPtr first)
{
/* Counts the number of points in the ring. */
gaiaPointPtr p = first;
int numpoints = 0;
while (p != NULL)
{
numpoints++;
p = p->Next;
}
return numpoints;
}
/*
* Creates a 2D (xy) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 2D (xy) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
ewkt_ring_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRing (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPoint (ring->Coords, index, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 3D (xyz) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 3D (xyz) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
ewkt_ring_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYZ (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZ (ring->Coords, index, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 2D (xym) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 2D (xym) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
ewkt_ring_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYM (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYM (ring->Coords, index, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 3D (xyzm) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 3D (xyzm) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
ewkt_ring_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYZM (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZM (ring->Coords, index, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Helper function that will create any type of polygon (xy, xym, xyz, xyzm) in SpatiaLite.
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are of the same type. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
ewkt_polygon_any_type (struct ewkt_data *p_data, gaiaRingPtr first)
{
gaiaRingPtr p;
gaiaRingPtr p_n;
gaiaPolygonPtr polygon;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a polygon structure with the exterior ring. */
polygon = gaiaCreatePolygon (first);
if (polygon == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_POLYGON, polygon);
/* Adds all interior rings into the polygon structure. */
p = first;
while (p != NULL)
{
p_n = p->Next;
ewktMapDynClean (p_data, p);
if (p == first)
gaiaFreeRing (p);
else
gaiaAddRingToPolyg (polygon, p);
p = p_n;
}
return polygon;
}
/*
* Creates a 2D (xy) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 2D (xy) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
ewkt_polygon_xy (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
/*
* Creates a 3D (xyz) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 3D (xyz) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
ewkt_polygon_xyz (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
/*
* Creates a 2D (xym) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 2D (xym) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
ewkt_polygon_xym (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
/*
* Creates a 3D (xyzm) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 3D (xyzm) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
ewkt_polygon_xyzm (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
/*
* Builds a geometry collection from a polygon.
* NOTE: This function may already be implemented in the SpatiaLite code base. If it is, make sure that we
* can use it (ie. it doesn't use any other variables or anything else set by Sandro's parser). If you find
* that we can use an existing function then ignore this one.
*/
static gaiaGeomCollPtr
ewkt_buildGeomFromPolygon (struct ewkt_data *p_data, gaiaPolygonPtr polygon)
{
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (polygon == NULL)
{
return NULL;
}
/* Creates and allocates a geometry collection containing a multipoint. */
switch (polygon->DimensionModel)
{
case GAIA_XY:
geom = gaiaAllocGeomColl ();
break;
case GAIA_XY_Z:
geom = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
geom = gaiaAllocGeomCollXYM ();
break;
case GAIA_XY_Z_M:
geom = gaiaAllocGeomCollXYZM ();
break;
}
if (geom == NULL)
{
return NULL;
}
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POLYGON;
/* Stores the location of the first and last polygons in the linked list. */
geom->FirstPolygon = polygon;
while (polygon != NULL)
{
ewktMapDynClean (p_data, polygon);
geom->LastPolygon = polygon;
polygon = polygon->Next;
}
return geom;
}
/*
* Creates a 2D (xy) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 2D (xy) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
ewkt_multipoint_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 2D (xy) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomColl (geom, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 3D (xyz) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 3D (xyz) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
ewkt_multipoint_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYZ ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 3D (xyz) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYZ (geom, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 2D (xym) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 2D (xym) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
ewkt_multipoint_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYM ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 2D (xym) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYM (geom, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 3D (xyzm) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points given to the function are 3D (xyzm) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
ewkt_multipoint_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYZM ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 3D (xyzm) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYZM (geom, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 2D (xy) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 2D (xy) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 2D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XY and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
ewkt_multilinestring_xy (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Returns a geometry collection containing the created multilinestring object (?).
* Creates a geometry collection containing 3D (xyz) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 3D (xyz) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 3D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the *list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XYZ and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
ewkt_multilinestring_xyz (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 2D (xy) with m value linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 2D (xy) with m value linestrings. There must be at least 1 linestring
* in the list.
* Returns a pointer to the created geometry collection of 2D with m value linestrings. The geometry must have FirstLinestring
* pointing to the first *linestring in the list pointed by first and LastLinestring pointing to the last element of the same list.
* DimensionModel must be GAIA_XYM and *DimensionType must be GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
ewkt_multilinestring_xym (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 4D (xyz) with m value linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 4D (xyz) with m value linestrings. There must be at least 1 linestring
* in the list.
* Returns a pointer to the created geometry collection of 4D with m value linestrings. The geometry must have FirstLinestring
* pointing to the first *linestring in the list pointed by first and LastLinestring pointing to the last element of the same list.
* DimensionModel must be GAIA_XYZM and *DimensionType must be GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
ewkt_multilinestring_xyzm (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 2D (xy) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should
* be added to the collection. All of the polygons in the list must be 2D (xy) polygons. There must be
* at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 2D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing
* to the last element of the same list. DimensionModel must be GAIA_XY and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
ewkt_multipolygon_xy (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 3D (xyz) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should be
* added to the collection. All of the polygons in the list must be 3D (xyz) polygons. There must be at
* least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 3D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing to
* the last element of the same list. DimensionModel must be GAIA_XYZ and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
ewkt_multipolygon_xyz (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 2D (xy) with m value polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should
* be added to the collection. All of the polygons in the list must be 2D (xy) with m value polygons.
* There must be at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 2D with m value polygons. The geometry
* must have FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon
* pointing to the last element of the same list. DimensionModel must be GAIA_XYM and DimensionType
* must be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
ewkt_multipolygon_xym (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 4D (xyz) with m value polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should be
* added to the collection. All of the polygons in the list must be 4D (xyz) with m value polygons.
* There must be at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 4D with m value polygons. The geometry must
* have FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing
// * to the last element of the same list. DimensionModel must be GAIA_XYZM and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
ewkt_multipolygon_xyzm (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static void
ewkt_geomColl_common (struct ewkt_data *p_data, gaiaGeomCollPtr org,
gaiaGeomCollPtr dst)
{
/*
/ helper function: xfers entities between the Origin and Destination
/ Sandro Furieri: 2010 October 12
*/
gaiaGeomCollPtr p = org;
gaiaGeomCollPtr p_n;
gaiaPointPtr pt;
gaiaPointPtr pt_n;
gaiaLinestringPtr ln;
gaiaLinestringPtr ln_n;
gaiaPolygonPtr pg;
gaiaPolygonPtr pg_n;
while (p)
{
pt = p->FirstPoint;
while (pt)
{
pt_n = pt->Next;
pt->Next = NULL;
if (dst->FirstPoint == NULL)
dst->FirstPoint = pt;
if (dst->LastPoint != NULL)
dst->LastPoint->Next = pt;
dst->LastPoint = pt;
pt = pt_n;
}
ln = p->FirstLinestring;
while (ln)
{
ln_n = ln->Next;
ln->Next = NULL;
if (dst->FirstLinestring == NULL)
dst->FirstLinestring = ln;
if (dst->LastLinestring != NULL)
dst->LastLinestring->Next = ln;
dst->LastLinestring = ln;
ln = ln_n;
}
pg = p->FirstPolygon;
while (pg)
{
pg_n = pg->Next;
pg->Next = NULL;
if (dst->FirstPolygon == NULL)
dst->FirstPolygon = pg;
if (dst->LastPolygon != NULL)
dst->LastPolygon->Next = pg;
dst->LastPolygon = pg;
pg = pg_n;
}
p_n = p->Next;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
ewktMapDynClean (p_data, p);
gaiaFreeGeomColl (p);
p = p_n;
}
}
/* Creates a 2D (xy) geometry collection in SpatiaLite
*
* first is the first geometry collection in a linked list of geometry collections.
* Each geometry collection represents a single type of object (eg. one could be a POINT,
* another could be a LINESTRING, another could be a MULTILINESTRING, etc.).
*
* The type of object represented by any geometry collection is stored in the declaredType
* field of its struct. For example, if first->declaredType = GAIA_POINT, then first represents a point.
* If first->declaredType = GAIA_MULTIPOINT, then first represents a multipoint.
*
* NOTE: geometry collections cannot contain other geometry collections (have to confirm this
* with Sandro).
*
* The goal of this function is to take the information from all of the structs in the linked list and
* return one geomColl struct containing all of that information.
*
* The integers used for 'declaredType' are defined in gaiageo.h. In this function, the only values
* contained in 'declaredType' that will be encountered will be:
*
* GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON,
* GAIA_MULTIPOINT, GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON
*/
static gaiaGeomCollPtr
ewkt_geomColl_xy (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTZ, GAIA_LINESTRINGZ, GAIA_POLYGONZ,
* GAIA_MULTIPOINTZ, GAIA_MULTILINESTRINGZ, GAIA_MULTIPOLYGONZ
*/
static gaiaGeomCollPtr
ewkt_geomColl_xyz (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTM, GAIA_LINESTRINGM, GAIA_POLYGONM,
* GAIA_MULTIPOINTM, GAIA_MULTILINESTRINGM, GAIA_MULTIPOLYGONM
*/
static gaiaGeomCollPtr
ewkt_geomColl_xym (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_M;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTZM, GAIA_LINESTRINGZM, GAIA_POLYGONZM,
* GAIA_MULTIPOINTZM, GAIA_MULTILINESTRINGZM, GAIA_MULTIPOLYGONZM
*/
static gaiaGeomCollPtr
ewkt_geomColl_xyzm (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z_M;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
/* including LEMON generated code */
#include "Ewkt.c"
/*
** CAVEAT: there is an incompatibility between LEMON and FLEX
** this macro resolves the issue
*/
#undef yy_accept
#define yy_accept yy_ewkt_flex_accept
/* including FLEX generated code */
#include "lex.Ewkt.c"
#line 3 "lex.Ewkt.c"
#define YY_INT_ALIGNED short int
/*
** This is a linked-list struct to store all the values for each token.
** All tokens will have a value of 0, except tokens denoted as NUM.
** NUM tokens are geometry coordinates and will contain the floating
** point number.
*/
typedef struct ewktFlexTokenStruct
{
double value;
struct ewktFlexTokenStruct *Next;
} ewktFlexToken;
/*
** Function to clean up the linked-list of token values.
*/
static int
ewkt_cleanup (ewktFlexToken * token)
{
ewktFlexToken *ptok;
ewktFlexToken *ptok_n;
if (token == NULL)
return 0;
ptok = token;
while (ptok)
{
ptok_n = ptok->Next;
free (ptok);
ptok = ptok_n;
}
return 0;
}
static int
findEwktSrid (const char *buffer, int *base_offset)
{
/* attempting to identify the EWKT SRID */
char dummy[1024];
char *out;
const char *in = buffer;
int end = -1;
int i;
*base_offset = 0;
while (*in != '\0')
{
/* searching the first semi-colon [srid delimiter] */
if (*in == ';')
{
end = in - buffer;
break;
}
in++;
}
if (end < 0)
return -1;
in = buffer;
out = dummy;
for (i = 0; i < end; i++)
{
/* normalizing whitespaces */
char c = *in;
if (c == ' ' || c == '\t' || c == '\n')
{
in++;
continue;
}
*out++ = *in++;
}
*out = '\0';
if (strncasecmp (dummy, "SRID=", 5) != 0)
return -1;
for (i = 5; i < (int) strlen (dummy); i++)
{
if (i == 5)
{
if (dummy[i] == '-' || dummy[i] == '+')
continue;
}
if (dummy[i] >= '0' && dummy[i] <= '9')
continue;
return -1;
}
*base_offset = end + 1;
return atoi (dummy + 5);
}
gaiaGeomCollPtr
gaiaParseEWKT (const unsigned char *dirty_buffer)
{
void *pParser = ParseAlloc (malloc);
/* Linked-list of token values */
ewktFlexToken *tokens = malloc (sizeof (ewktFlexToken));
/* Pointer to the head of the list */
ewktFlexToken *head = tokens;
int yv;
int srid;
int base_offset;
yyscan_t scanner;
struct ewkt_data str_data;
/* initializing the helper structs */
str_data.ewkt_line = 1;
str_data.ewkt_col = 1;
str_data.ewkt_parse_error = 0;
str_data.ewkt_first_dyn_block = NULL;
str_data.ewkt_last_dyn_block = NULL;
str_data.result = NULL;
/* initializing the scanner state */
Ewktlex_init_extra (&str_data, &scanner);
tokens->Next = NULL;
srid = findEwktSrid ((char *) dirty_buffer, &base_offset);
Ewkt_scan_string ((char *) dirty_buffer + base_offset, scanner);
/*
/ Keep tokenizing until we reach the end
/ yylex() will return the next matching Token for us.
*/
while ((yv = yylex (scanner)) != 0)
{
if (yv == -1)
{
str_data.ewkt_parse_error = 1;
break;
}
tokens->Next = malloc (sizeof (ewktFlexToken));
tokens->Next->Next = NULL;
tokens->Next->value = str_data.EwktLval.dval;
/* Pass the token to the wkt parser created from lemon */
Parse (pParser, yv, &(tokens->Next->value), &str_data);
tokens = tokens->Next;
}
/* This denotes the end of a line as well as the end of the parser */
Parse (pParser, EWKT_NEWLINE, 0, &str_data);
ParseFree (pParser, free);
Ewktlex_destroy (scanner);
/* Assigning the token as the end to avoid seg faults while cleaning */
tokens->Next = NULL;
ewkt_cleanup (head);
if (str_data.ewkt_parse_error)
{
if (str_data.result)
{
/* if a Geometry-result has been produced, the stack is already cleaned */
gaiaFreeGeomColl (str_data.result);
ewktCleanMapDynAlloc (&str_data, 0);
}
else
{
/* otherwise we are required to clean the stack */
ewktCleanMapDynAlloc (&str_data, 1);
}
return NULL;
}
ewktCleanMapDynAlloc (&str_data, 0);
if (str_data.result == NULL)
return NULL;
if (!ewktCheckValidity (str_data.result))
{
gaiaFreeGeomColl (str_data.result);
return NULL;
}
gaiaMbrGeometry (str_data.result);
str_data.result->Srid = srid;
return str_data.result;
}
/*
** CAVEAT: we must now undefine any Lemon/Flex own macro
*/
#undef YYNOCODE
#undef YYNSTATE
#undef YYNRULE
#undef YY_SHIFT_MAX
#undef YY_SHIFT_USE_DFLT
#undef YY_REDUCE_USE_DFLT
#undef YY_REDUCE_MAX
#undef YY_FLUSH_BUFFER
#undef YY_DO_BEFORE_ACTION
#undef YY_NUM_RULES
#undef YY_END_OF_BUFFER
#undef YY_END_FILE
#undef YYACTIONTYPE
#undef YY_SZ_ACTTAB
#undef YY_NEW_FILE
#undef BEGIN
#undef YY_START
#undef YY_CURRENT_BUFFER
#undef YY_CURRENT_BUFFER_LVALUE
#undef YY_STATE_BUF_SIZE
#undef YY_DECL
#undef YY_FATAL_ERROR
#undef YYMINORTYPE
#undef YY_CHAR
#undef YYSTYPE
#undef input
#undef ParseAlloc
#undef ParseFree
#undef ParseStackPeak
#undef Parse
#undef yyalloc
#undef yyfree
#undef yyin
#undef yyleng
#undef yyless
#undef yylex
#undef yylineno
#undef yyout
#undef yyrealloc
#undef yyrestart
#undef yyStackEntry
#undef yytext
#undef yywrap
#undef yyzerominor
#undef yy_accept
#undef yy_action
#undef yy_base
#undef yy_buffer_stack
#undef yy_buffer_stack_max
#undef yy_buffer_stack_top
#undef yy_c_buf_p
#undef yy_chk
#undef yy_create_buffer
#undef yy_def
#undef yy_default
#undef yy_delete_buffer
#undef yy_destructor
#undef yy_ec
#undef yy_fatal_error
#undef yy_find_reduce_action
#undef yy_find_shift_action
#undef yy_flex_debug
#undef yy_flush_buffer
#undef yy_get_next_buffer
#undef yy_get_previous_state
#undef yy_init
#undef yy_init_buffer
#undef yy_init_globals
#undef yy_load_buffer
#undef yy_load_buffer_state
#undef yy_lookahead
#undef yy_meta
#undef yy_new_buffer
#undef yy_nxt
#undef yy_parse_failed
#undef yy_pop_parser_stack
#undef yy_reduce
#undef yy_reduce_ofst
#undef yy_set_bol
#undef yy_set_interactive
#undef yy_shift
#undef yy_shift_ofst
#undef yy_start
#undef yy_state_type
#undef yy_switch_to_buffer
#undef yy_syntax_error
#undef yy_trans_info
#undef yy_try_NUL_trans
#undef yyParser
#undef yyStackEntry
#undef yyStackOverflow
#undef yyRuleInfo
#undef yytext_ptr
#undef yyunput
#undef yyzerominor
#undef ParseARG_SDECL
#undef ParseARG_PDECL
#undef ParseARG_FETCH
#undef ParseARG_STORE
#undef REJECT
#undef yymore
#undef YY_MORE_ADJ
#undef YY_RESTORE_YY_MORE_OFFSET
#undef YY_LESS_LINENO
#undef yyTracePrompt
#undef yyTraceFILE
#undef yyTokenName
#undef yyRuleName
#undef ParseTrace
#undef yylex
#undef YY_DECL
libspatialite-5.1.0/src/gaiageo/gg_geoJSON.c 0000644 0001750 0001750 00000136320 14463127014 015543 0000000 0000000 /*
gg_geoJSON.c -- GeoJSON parser/lexer
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2011-2023
the Initial Developer. All Rights Reserved.
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#include
#else
#include "config.h"
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
#define isatty _isatty
#define fileno _fileno
#endif
#include
#include
#include
#define GEOJSON_DYN_NONE 0
#define GEOJSON_DYN_POINT 1
#define GEOJSON_DYN_LINESTRING 2
#define GEOJSON_DYN_POLYGON 3
#define GEOJSON_DYN_RING 4
#define GEOJSON_DYN_GEOMETRY 5
#define GEOJSON_DYN_BLOCK 1024
/*
** CAVEAT: we must redefine any Lemon/Flex own macro
*/
#define YYMINORTYPE GEO_JSON_MINORTYPE
#define YY_CHAR GEO_JSON_YY_CHAR
#define input geoJSON_input
#define ParseAlloc geoJSONParseAlloc
#define ParseFree geoJSONParseFree
#define ParseStackPeak geoJSONParseStackPeak
#define Parse geoJSONParse
#define yyStackEntry geoJSON_yyStackEntry
#define yyzerominor geoJSON_yyzerominor
#define yy_accept geoJSON_yy_accept
#define yy_action geoJSON_yy_action
#define yy_base geoJSON_yy_base
#define yy_buffer_stack geoJSON_yy_buffer_stack
#define yy_buffer_stack_max geoJSON_yy_buffer_stack_max
#define yy_buffer_stack_top geoJSON_yy_buffer_stack_top
#define yy_c_buf_p geoJSON_yy_c_buf_p
#define yy_chk geoJSON_yy_chk
#define yy_def geoJSON_yy_def
#define yy_default geoJSON_yy_default
#define yy_destructor geoJSON_yy_destructor
#define yy_ec geoJSON_yy_ec
#define yy_fatal_error geoJSON_yy_fatal_error
#define yy_find_reduce_action geoJSON_yy_find_reduce_action
#define yy_find_shift_action geoJSON_yy_find_shift_action
#define yy_get_next_buffer geoJSON_yy_get_next_buffer
#define yy_get_previous_state geoJSON_yy_get_previous_state
#define yy_init geoJSON_yy_init
#define yy_init_globals geoJSON_yy_init_globals
#define yy_lookahead geoJSON_yy_lookahead
#define yy_meta geoJSON_yy_meta
#define yy_nxt geoJSON_yy_nxt
#define yy_parse_failed geoJSON_yy_parse_failed
#define yy_pop_parser_stack geoJSON_yy_pop_parser_stack
#define yy_reduce geoJSON_yy_reduce
#define yy_reduce_ofst geoJSON_yy_reduce_ofst
#define yy_shift geoJSON_yy_shift
#define yy_shift_ofst geoJSON_yy_shift_ofst
#define yy_start geoJSON_yy_start
#define yy_state_type geoJSON_yy_state_type
#define yy_syntax_error geoJSON_yy_syntax_error
#define yy_trans_info geoJSON_yy_trans_info
#define yy_try_NUL_trans geoJSON_yy_try_NUL_trans
#define yyParser geoJSON_yyParser
#define yyStackEntry geoJSON_yyStackEntry
#define yyStackOverflow geoJSON_yyStackOverflow
#define yyRuleInfo geoJSON_yyRuleInfo
#define yyunput geoJSON_yyunput
#define yyzerominor geoJSON_yyzerominor
#define yyTraceFILE geoJSON_yyTraceFILE
#define yyTracePrompt geoJSON_yyTracePrompt
#define yyTokenName geoJSON_yyTokenName
#define yyRuleName geoJSON_yyRuleName
#define ParseTrace geoJSON_ParseTrace
#define yylex geoJSON_yylex
#define YY_DECL int yylex (yyscan_t yyscanner)
/* including LEMON generated header */
#include "geoJSON.h"
typedef union
{
double dval;
int ival;
struct symtab *symp;
} geoJSON_yystype;
#define YYSTYPE geoJSON_yystype
struct geoJson_dyn_block
{
/* a struct taking trace of dynamic allocations */
int type[GEOJSON_DYN_BLOCK];
void *ptr[GEOJSON_DYN_BLOCK];
int index;
struct geoJson_dyn_block *next;
};
struct geoJson_data
{
/* a struct used to make the lexer-parser reentrant and thread-safe */
int geoJson_parse_error;
int geoJson_line;
int geoJson_col;
struct geoJson_dyn_block *geoJson_first_dyn_block;
struct geoJson_dyn_block *geoJson_last_dyn_block;
gaiaGeomCollPtr result;
YYSTYPE GeoJsonLval;
};
static struct geoJson_dyn_block *
geoJsonCreateDynBlock (void)
{
/* allocating a new block to trace dynamic allocations */
int i;
struct geoJson_dyn_block *p = malloc (sizeof (struct geoJson_dyn_block));
for (i = 0; i < GEOJSON_DYN_BLOCK; i++)
{
/* initializing map entries */
p->type[i] = GEOJSON_DYN_NONE;
p->ptr[i] = NULL;
}
p->index = 0;
p->next = NULL;
return p;
}
static void
geoJsonMapDynAlloc (struct geoJson_data *p_data, int type, void *ptr)
{
/* appending a dynamic allocation into the map */
struct geoJson_dyn_block *p;
if (p_data->geoJson_first_dyn_block == NULL)
{
/* inserting the first block of the map */
p = geoJsonCreateDynBlock ();
p_data->geoJson_first_dyn_block = p;
p_data->geoJson_last_dyn_block = p;
}
if (p_data->geoJson_last_dyn_block->index >= GEOJSON_DYN_BLOCK)
{
/* adding a further block to the map */
p = geoJsonCreateDynBlock ();
p_data->geoJson_last_dyn_block->next = p;
p_data->geoJson_last_dyn_block = p;
}
p_data->geoJson_last_dyn_block->type[p_data->geoJson_last_dyn_block->
index] = type;
p_data->geoJson_last_dyn_block->ptr[p_data->geoJson_last_dyn_block->index] =
ptr;
p_data->geoJson_last_dyn_block->index++;
}
static void
geoJsonMapDynClean (struct geoJson_data *p_data, void *ptr)
{
/* deleting a dynamic allocation from the map */
int i;
struct geoJson_dyn_block *p = p_data->geoJson_first_dyn_block;
while (p)
{
for (i = 0; i < GEOJSON_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case GEOJSON_DYN_POINT:
case GEOJSON_DYN_LINESTRING:
case GEOJSON_DYN_POLYGON:
case GEOJSON_DYN_RING:
case GEOJSON_DYN_GEOMETRY:
if (p->ptr[i] == ptr)
{
p->type[i] = GEOJSON_DYN_NONE;
return;
}
break;
};
}
p = p->next;
}
}
static void
geoJsonCleanMapDynAlloc (struct geoJson_data *p_data, int clean_all)
{
/* cleaning the dynamic allocations map */
int i;
struct geoJson_dyn_block *pn;
struct geoJson_dyn_block *p = p_data->geoJson_first_dyn_block;
while (p)
{
if (clean_all)
{
for (i = 0; i < GEOJSON_DYN_BLOCK; i++)
{
/* deleting Geometry objects */
switch (p->type[i])
{
case GEOJSON_DYN_POINT:
gaiaFreePoint ((gaiaPointPtr) (p->ptr[i]));
break;
case GEOJSON_DYN_LINESTRING:
gaiaFreeLinestring ((gaiaLinestringPtr)
(p->ptr[i]));
break;
case GEOJSON_DYN_POLYGON:
gaiaFreePolygon ((gaiaPolygonPtr) (p->ptr[i]));
break;
case GEOJSON_DYN_RING:
gaiaFreeRing ((gaiaRingPtr) (p->ptr[i]));
break;
case GEOJSON_DYN_GEOMETRY:
gaiaFreeGeomColl ((gaiaGeomCollPtr) (p->ptr[i]));
break;
};
}
}
/* deleting the map block */
pn = p->next;
free (p);
p = pn;
}
}
static int
geoJsonCheckValidity (gaiaGeomCollPtr geom)
{
/* checks if this one is a degenerated geometry */
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int ib;
int entities = 0;
pt = geom->FirstPoint;
while (pt)
{
/* checking points */
entities++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
/* checking linestrings */
if (ln->Points < 2)
return 0;
entities++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
/* checking polygons */
rng = pg->Exterior;
if (rng->Points < 4)
return 0;
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
if (rng->Points < 4)
return 0;
}
entities++;
pg = pg->Next;
}
if (!entities)
return 0;
return 1;
}
static gaiaGeomCollPtr
geoJSON_setSrid (gaiaGeomCollPtr geom, int *srid)
{
/* setting up the SRID */
if (!geom)
return NULL;
geom->Srid = *srid;
return geom;
}
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromPoint (struct geoJson_data *p_data, gaiaPointPtr point,
int srid)
{
/* builds a GEOMETRY containing a POINT */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomColl ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINT;
geom->Srid = srid;
gaiaAddPointToGeomColl (geom, point->X, point->Y);
geoJsonMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromPointZ (struct geoJson_data *p_data, gaiaPointPtr point,
int srid)
{
/* builds a GEOMETRY containing a POINTZ */
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZ ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZ;
geom->Srid = srid;
gaiaAddPointToGeomCollXYZ (geom, point->X, point->Y, point->Z);
geoJsonMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromLinestring (struct geoJson_data *p_data,
gaiaLinestringPtr line, int srid)
{
/* builds a GEOMETRY containing a LINESTRING */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
geom = gaiaAllocGeomColl ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
geom->Srid = srid;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPoint (line->Coords, iv, &x, &y);
gaiaSetPoint (line2->Coords, iv, x, y);
}
geoJsonMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromLinestringZ (struct geoJson_data *p_data,
gaiaLinestringPtr line, int srid)
{
/* builds a GEOMETRY containing a LINESTRINGZ */
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
geom = gaiaAllocGeomCollXYZ ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
geom->Srid = srid;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
/* sets the POINTS for the exterior ring */
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
geoJsonMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaPointPtr
geoJSON_point_xy (struct geoJson_data *p_data, double *x, double *y)
{
gaiaPointPtr pt = gaiaAllocPoint (*x, *y);
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_POINT, pt);
return pt;
}
/*
* Creates a 3D (xyz) point in SpatiaLite
* x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr representing the created point.
*
* Creates a 3D (xyz) point. This is a parser helper function which is called when 3D coordinates are encountered.
* Parameters x, y, and z are pointers to doubles which represent the x, y, and z coordinates of the point to be created.
* Returns a gaiaPointPtr pointing to the 3D created point.
*/
static gaiaPointPtr
geoJSON_point_xyz (struct geoJson_data *p_data, double *x, double *y, double *z)
{
gaiaPointPtr pt = gaiaAllocPointXYZ (*x, *y, *z);
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_POINT, pt);
return pt;
}
/*
* Builds a geometry collection from a point. The geometry collection should contain only one element ? the point.
* The correct geometry type must be *decided based on the point type. The parser should call this function when the
* ?POINT? WKT expression is encountered.
* Parameter point is a pointer to a 2D, 3D, 2D with an m value, or 4D with an m value point.
* Returns a geometry collection containing the point. The geometry must have FirstPoint and LastPoint pointing to the
* same place as point. *DimensionModel must be the same as the model of the point and DimensionType must be GAIA_TYPE_POINT.
*/
static gaiaGeomCollPtr
geoJSON_buildGeomFromPoint (struct geoJson_data *p_data, gaiaPointPtr point)
{
switch (point->DimensionModel)
{
case GAIA_XY:
return gaiaGeoJsonGeometryFromPoint (p_data, point, -1);
case GAIA_XY_Z:
return gaiaGeoJsonGeometryFromPointZ (p_data, point, -1);
}
return NULL;
}
static gaiaGeomCollPtr
geoJSON_buildGeomFromPointSrid (struct geoJson_data *p_data, gaiaPointPtr point,
int *srid)
{
switch (point->DimensionModel)
{
case GAIA_XY:
return gaiaGeoJsonGeometryFromPoint (p_data, point, *srid);
case GAIA_XY_Z:
return gaiaGeoJsonGeometryFromPointZ (p_data, point, *srid);
}
return NULL;
}
/*
* Creates a 2D (xy) linestring from a list of 2D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 2D (xy) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
geoJSON_linestring_xy (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestring (points);
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPoint (linestring->Coords, i, p->X, p->Y);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Creates a 3D (xyz) linestring from a list of 3D points.
*
* Parameter first is a gaiaPointPtr to the first point in a linked list of points which define the linestring.
* All of the points in the list must be 3D (xyz) points. There must be at least 2 points in the list.
*
* Returns a pointer to linestring containing all of the points in the list.
*/
static gaiaLinestringPtr
geoJSON_linestring_xyz (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZ (points);
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZ (linestring->Coords, i, p->X, p->Y, p->Z);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
/*
* Builds a geometry collection from a linestring.
*/
static gaiaGeomCollPtr
geoJSON_buildGeomFromLinestring (struct geoJson_data *p_data,
gaiaLinestringPtr line)
{
switch (line->DimensionModel)
{
case GAIA_XY:
return gaiaGeoJsonGeometryFromLinestring (p_data, line, -1);
case GAIA_XY_Z:
return gaiaGeoJsonGeometryFromLinestringZ (p_data, line, -1);
}
return NULL;
}
static gaiaGeomCollPtr
geoJSON_buildGeomFromLinestringSrid (struct geoJson_data *p_data,
gaiaLinestringPtr line, int *srid)
{
switch (line->DimensionModel)
{
case GAIA_XY:
return gaiaGeoJsonGeometryFromLinestring (p_data, line, *srid);
case GAIA_XY_Z:
return gaiaGeoJsonGeometryFromLinestringZ (p_data, line, *srid);
}
return NULL;
}
/*
* Helper function that determines the number of points in the linked list.
*/
static int
geoJSON_count_points (gaiaPointPtr first)
{
/* Counts the number of points in the ring. */
gaiaPointPtr p = first;
int numpoints = 0;
while (p != NULL)
{
numpoints++;
p = p->Next;
}
return numpoints;
}
/*
* Creates a 2D (xy) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 2D (xy) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
geoJSON_ring_xy (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = geoJSON_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRing (numpoints);
if (ring == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPoint (ring->Coords, index, p->X, p->Y);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Creates a 3D (xyz) ring in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points which define the polygon.
* All of the points given to the function are 3D (xyz) points. There will be at least 4 points in the list.
*
* Returns the ring defined by the points given to the function.
*/
static gaiaRingPtr
geoJSON_ring_xyz (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Counts the number of points in the ring. */
numpoints = geoJSON_count_points (first);
if (numpoints < 4)
return NULL;
/* Creates and allocates a ring structure. */
ring = gaiaAllocRingXYZ (numpoints);
if (ring == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_RING, ring);
/* Adds every point into the ring structure. */
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZ (ring->Coords, index, p->X, p->Y, p->Z);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
/*
* Helper function that will create any type of polygon (xy, xyz) in SpatiaLite.
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are of the same type. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
geoJSON_polygon_any_type (struct geoJson_data *p_data, gaiaRingPtr first)
{
gaiaRingPtr p;
gaiaRingPtr p_n;
gaiaPolygonPtr polygon;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a polygon structure with the exterior ring. */
polygon = gaiaCreatePolygon (first);
if (polygon == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_POLYGON, polygon);
/* Adds all interior rings into the polygon structure. */
p = first;
while (p != NULL)
{
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
if (p == first)
gaiaFreeRing (p);
else
gaiaAddRingToPolyg (polygon, p);
p = p_n;
}
return polygon;
}
/*
* Creates a 2D (xy) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 2D (xy) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
geoJSON_polygon_xy (struct geoJson_data *p_data, gaiaRingPtr first)
{
return geoJSON_polygon_any_type (p_data, first);
}
/*
* Creates a 3D (xyz) polygon in SpatiaLite
*
* first is a gaiaRingPtr to the first ring in a linked list of rings which define the polygon.
* The first ring in the linked list is the external ring while the rest (if any) are internal rings.
* All of the rings given to the function are 3D (xyz) rings. There will be at least 1 ring in the list.
*
* Returns the polygon defined by the rings given to the function.
*/
static gaiaPolygonPtr
geoJSON_polygon_xyz (struct geoJson_data *p_data, gaiaRingPtr first)
{
return geoJSON_polygon_any_type (p_data, first);
}
/*
* Builds a geometry collection from a polygon.
* NOTE: This function may already be implemented in the SpatiaLite code base. If it is, make sure that we
* can use it (ie. it doesn't use any other variables or anything else set by Sandro's parser). If you find
* that we can use an existing function then ignore this one.
*/
static gaiaGeomCollPtr
geoJSON_buildGeomFromPolygon (struct geoJson_data *p_data,
gaiaPolygonPtr polygon)
{
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (polygon == NULL)
{
return NULL;
}
/* Creates and allocates a geometry collection containing a multipoint. */
switch (polygon->DimensionModel)
{
case GAIA_XY:
geom = gaiaAllocGeomColl ();
break;
case GAIA_XY_Z:
geom = gaiaAllocGeomCollXYZ ();
break;
}
if (geom == NULL)
{
return NULL;
}
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POLYGON;
/* Stores the location of the first and last polygons in the linked list. */
geom->FirstPolygon = polygon;
while (polygon != NULL)
{
geoJsonMapDynClean (p_data, polygon);
geom->LastPolygon = polygon;
polygon = polygon->Next;
}
return geom;
}
static gaiaGeomCollPtr
geoJSON_buildGeomFromPolygonSrid (struct geoJson_data *p_data,
gaiaPolygonPtr polygon, int *srid)
{
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (polygon == NULL)
{
return NULL;
}
/* Creates and allocates a geometry collection containing a multipoint. */
switch (polygon->DimensionModel)
{
case GAIA_XY:
geom = gaiaAllocGeomColl ();
break;
case GAIA_XY_Z:
geom = gaiaAllocGeomCollXYZ ();
break;
}
if (geom == NULL)
{
return NULL;
}
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POLYGON;
geom->Srid = *srid;
/* Stores the location of the first and last polygons in the linked list. */
geom->FirstPolygon = polygon;
while (polygon != NULL)
{
geoJsonMapDynClean (p_data, polygon);
geom->LastPolygon = polygon;
polygon = polygon->Next;
}
return geom;
}
/*
* Creates a 2D (xy) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 2D (xy) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
geoJSON_multipoint_xy (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 2D (xy) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomColl (geom, p->X, p->Y);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a 3D (xyz) multipoint object in SpatiaLite
*
* first is a gaiaPointPtr to the first point in a linked list of points.
* All of the points given to the function are 3D (xyz) points. There will be at least 1 point in the list.
*
* Returns a geometry collection containing the created multipoint object.
*/
static gaiaGeomCollPtr
geoJSON_multipoint_xyz (struct geoJson_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
/* If no pointers are given, return. */
if (first == NULL)
return NULL;
/* Creates and allocates a geometry collection containing a multipoint. */
geom = gaiaAllocGeomCollXYZ ();
if (geom == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
/* For every 3D (xyz) point, add it to the geometry collection. */
while (p != NULL)
{
gaiaAddPointToGeomCollXYZ (geom, p->X, p->Y, p->Z);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 2D (xy) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 2D (xy) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 2D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XY and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
geoJSON_multilinestring_xy (struct geoJson_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomColl ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Returns a geometry collection containing the created multilinestring object (?).
* Creates a geometry collection containing 3D (xyz) linestrings.
* Parameter first is a gaiaLinestringPtr to the first linestring in a linked list of linestrings which should be added to the
* collection. All of the *linestrings in the list must be 3D (xyz) linestrings. There must be at least 1 linestring in the list.
* Returns a pointer to the created geometry collection of 3D linestrings. The geometry must have FirstLinestring pointing to the
* first linestring in the *list pointed by first and LastLinestring pointing to the last element of the same list. DimensionModel
* must be GAIA_XYZ and DimensionType must be *GAIA_TYPE_LINESTRING.
*/
static gaiaGeomCollPtr
geoJSON_multilinestring_xyz (struct geoJson_data *p_data,
gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZ ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
/*
* Creates a geometry collection containing 2D (xy) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should
* be added to the collection. All of the polygons in the list must be 2D (xy) polygons. There must be
* at least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 2D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing
* to the last element of the same list. DimensionModel must be GAIA_XY and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
geoJSON_multipolygon_xy (struct geoJson_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
/*
* Creates a geometry collection containing 3D (xyz) polygons.
*
* Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should be
* added to the collection. All of the polygons in the list must be 3D (xyz) polygons. There must be at
* least 1 polygon in the list.
*
* Returns a pointer to the created geometry collection of 3D polygons. The geometry must have
* FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing to
* the last element of the same list. DimensionModel must be GAIA_XYZ and DimensionType must
* be GAIA_TYPE_POLYGON.
*
*/
static gaiaGeomCollPtr
geoJSON_multipolygon_xyz (struct geoJson_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZ ();
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
geoJsonMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static void
geoJSON_geomColl_common (struct geoJson_data *p_data, gaiaGeomCollPtr org,
gaiaGeomCollPtr dst)
{
/*
/ helper function: xfers entities between the Origin and Destination
/ Sandro Furieri: 2010 October 12
*/
gaiaGeomCollPtr p = org;
gaiaGeomCollPtr p_n;
gaiaPointPtr pt;
gaiaPointPtr pt_n;
gaiaLinestringPtr ln;
gaiaLinestringPtr ln_n;
gaiaPolygonPtr pg;
gaiaPolygonPtr pg_n;
while (p)
{
pt = p->FirstPoint;
while (pt)
{
pt_n = pt->Next;
pt->Next = NULL;
if (dst->FirstPoint == NULL)
dst->FirstPoint = pt;
if (dst->LastPoint != NULL)
dst->LastPoint->Next = pt;
dst->LastPoint = pt;
pt = pt_n;
}
ln = p->FirstLinestring;
while (ln)
{
ln_n = ln->Next;
ln->Next = NULL;
if (dst->FirstLinestring == NULL)
dst->FirstLinestring = ln;
if (dst->LastLinestring != NULL)
dst->LastLinestring->Next = ln;
dst->LastLinestring = ln;
ln = ln_n;
}
pg = p->FirstPolygon;
while (pg)
{
pg_n = pg->Next;
pg->Next = NULL;
if (dst->FirstPolygon == NULL)
dst->FirstPolygon = pg;
if (dst->LastPolygon != NULL)
dst->LastPolygon->Next = pg;
dst->LastPolygon = pg;
pg = pg_n;
}
p_n = p->Next;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
geoJsonMapDynClean (p_data, p);
gaiaFreeGeomColl (p);
p = p_n;
}
}
/* Creates a 2D (xy) geometry collection in SpatiaLite
*
* first is the first geometry collection in a linked list of geometry collections.
* Each geometry collection represents a single type of object (eg. one could be a POINT,
* another could be a LINESTRING, another could be a MULTILINESTRING, etc.).
*
* The type of object represented by any geometry collection is stored in the declaredType
* field of its struct. For example, if first->declaredType = GAIA_POINT, then first represents a point.
* If first->declaredType = GAIA_MULTIPOINT, then first represents a multipoint.
*
* NOTE: geometry collections cannot contain other geometry collections (have to confirm this
* with Sandro).
*
* The goal of this function is to take the information from all of the structs in the linked list and
* return one geomColl struct containing all of that information.
*
* The integers used for 'declaredType' are defined in gaiageo.h. In this function, the only values
* contained in 'declaredType' that will be encountered will be:
*
* GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON,
* GAIA_MULTIPOINT, GAIA_MULTILINESTRING, GAIA_MULTIPOLYGON
*/
static gaiaGeomCollPtr
geoJSON_geomColl_xy (struct geoJson_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY;
geoJSON_geomColl_common (p_data, first, geom);
return geom;
}
/*
* See geomColl_xy for description.
*
* The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
* in the linked list for this function will only contain the following types:
*
* GAIA_POINTZ, GAIA_LINESTRINGZ, GAIA_POLYGONZ,
* GAIA_MULTIPOINTZ, GAIA_MULTILINESTRINGZ, GAIA_MULTIPOLYGONZ
*/
static gaiaGeomCollPtr
geoJSON_geomColl_xyz (struct geoJson_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z;
geoJSON_geomColl_common (p_data, first, geom);
return geom;
}
/* including LEMON generated code */
#include "geoJSON.c"
/*
** CAVEAT: there is an incompatibility between LEMON and FLEX
** this macro resolves the issue
*/
#undef yy_accept
#define yy_accept yy_geo_json_flex_accept
/* including FLEX generated code */
#include "lex.GeoJson.c"
/*
** This is a linked-list struct to store all the values for each token.
** All tokens will have a value of 0, except tokens denoted as NUM.
** NUM tokens are geometry coordinates and will contain the floating
** point number.
*/
typedef struct geoJsonFlexTokenStruct
{
double value;
struct geoJsonFlexTokenStruct *Next;
} geoJsonFlexToken;
/*
** Function to clean up the linked-list of token values.
*/
static int
geoJSON_cleanup (geoJsonFlexToken * token)
{
geoJsonFlexToken *ptok;
geoJsonFlexToken *ptok_n;
if (token == NULL)
return 0;
ptok = token;
while (ptok)
{
ptok_n = ptok->Next;
free (ptok);
ptok = ptok_n;
}
return 0;
}
static int
geoJSONlen (int start, int e1, int e2, int e3, int e4, int len)
{
/* computing an item length */
int end = len;
if (start < 0)
return -1;
if (e1 > start && e1 < end)
end = e1;
if (e2 > start && e2 < end)
end = e2;
if (e3 > start && e3 < end)
end = e3;
if (e4 > start && e4 < end)
end = e4;
return end;
}
static char *
geoJSONuncomma (const char *str, int i_str, int n_str)
{
/* removing an eventual trailing COMMA */
int i;
int comma = 1;
int out = 0;
char *norm = malloc (n_str + 1);
for (i = i_str; i < n_str; i++)
{
/* copying bytes */
*(norm + out) = *(str + i);
out++;
}
*(norm + out) = '\0';
for (i = out - 1; i >= 0; i--)
{
if (*(norm + i) == ' ' || *(norm + i) == '\t' || *(norm + i) == '\n'
|| *(norm + i) == '\r')
{
/*ignoring trailing WHITESPACES */
*(norm + i) = '\0';
continue;
}
if (*(norm + i) == ',' && comma)
{
/* suppressing a final COMMA */
*(norm + i) = '\0';
comma = 0;
}
break;
}
return norm;
}
static int
geoJSONcheckType (const char *str, int pos)
{
/* testing for a Geometry Type */
int pos1 = -1;
int i;
int len = strlen (str);
for (i = pos; i < len; i++)
{
if (*(str + i) == ':')
{
pos1 = i + 1;
break;
}
}
if (pos1 < 0)
return 0;
for (i = pos1; i < len; i++)
{
if (*(str + i) == ',')
break;
if ((i + 7) <= len && strncmp (str + i, "\"Point\"", 7) == 0)
return 1;
if ((i + 12) <= len && strncmp (str + i, "\"LineString\"", 12) == 0)
return 1;
if ((i + 9) <= len && strncmp (str + i, "\"Polygon\"", 9) == 0)
return 1;
if ((i + 12) <= len && strncmp (str + i, "\"MultiPoint\"", 12) == 0)
return 1;
if ((i + 17) <= len
&& strncmp (str + i, "\"MultiLineString\"", 17) == 0)
return 1;
if ((i + 14) <= len && strncmp (str + i, "\"MultiPolygon\"", 14) == 0)
return 1;
if ((i + 20) <= len
&& strncmp (str + i, "\"GeometryCollection\"", 20) == 0)
return 1;
}
return 0;
}
static int
geoJSONcheckGeomCollType (const char *str, int pos)
{
/* testing for a GeometryCollection Type */
int pos1 = -1;
int i;
int len = strlen (str);
for (i = pos; i < len; i++)
{
if (*(str + i) == ':')
{
pos1 = i + 1;
break;
}
}
if (pos1 < 0)
return 0;
for (i = pos1; i < len; i++)
{
if (*(str + i) == ',')
break;
if ((i + 20) <= len
&& strncmp (str + i, "\"GeometryCollection\"", 20) == 0)
return 1;
}
return 0;
}
static char *
geoJSONnormalize (const char *dirty)
{
/* attempting to normalize the geoJSON expression */
int len = strlen (dirty);
char *clean;
char *norm;
int i;
int i_type = -1;
int i_geometries = -1;
int i_coordinates = -1;
int i_crs = -1;
int i_bbox = -1;
int i_end = -1;
int n_type = -1;
int n_geometries = -1;
int n_coordinates = -1;
int n_crs = -1;
int n_bbox = -1;
int base;
int out = 0;
for (i = 0; i < len; i++)
{
/* hi-priority: searching for GeometryCollection */
if (i_type < 0 && (i + 6) < len
&& strncmp (dirty + i, "\"type\"", 6) == 0)
{
if (geoJSONcheckGeomCollType (dirty, i + 6))
i_type = i;
}
}
for (i = 0; i < len; i++)
{
/* searching the start index for each item */
if (*(dirty + i) == '}')
i_end = i;
if (i_type < 0 && (i + 6) < len
&& strncmp (dirty + i, "\"type\"", 6) == 0)
{
if (geoJSONcheckType (dirty, i + 6))
i_type = i;
}
if (i_geometries < 0 && (i + 12) < len
&& strncmp (dirty + i, "\"geometries\"", 12) == 0)
i_geometries = i;
if (i_coordinates < 0 && (i + 13) < len
&& strncmp (dirty + i, "\"coordinates\"", 13) == 0)
i_coordinates = i;
if (i_crs < 0 && (i + 5) < len
&& strncmp (dirty + i, "\"crs\"", 5) == 0)
i_crs = i;
if (i_bbox < 0 && (i + 6) < len
&& strncmp (dirty + i, "\"bbox\"", 6) == 0)
i_bbox = i;
}
if (i_geometries >= 0)
i_coordinates = i_geometries;
n_type = geoJSONlen (i_type, i_coordinates, i_crs, i_bbox, i_end, len);
n_coordinates =
geoJSONlen (i_coordinates, i_type, i_crs, i_bbox, i_end, len);
n_crs = geoJSONlen (i_crs, i_coordinates, i_type, i_bbox, i_end, len);
n_bbox = geoJSONlen (i_bbox, i_coordinates, i_type, i_crs, i_end, len);
clean = malloc (len + 1);
if (i_end < 0)
{
strcpy (clean, dirty);
return clean;
}
if (i_type < 0 || n_type <= 0)
{
strcpy (clean, dirty);
return clean;
}
if (i_coordinates < 0 || n_coordinates <= 0)
{
strcpy (clean, dirty);
return clean;
}
if (i_crs >= 0 && n_crs <= 0)
{
strcpy (clean, dirty);
return clean;
}
if (i_bbox >= 0 && n_bbox <= 0)
{
strcpy (clean, dirty);
return clean;
}
base = i_type;
if (i_coordinates < base)
base = i_coordinates;
if (i_crs >= 0 && i_crs < base)
base = i_crs;
if (i_bbox >= 0 && i_bbox < base)
base = i_bbox;
for (i = 0; i < base; i++)
{
/* preamble */
*(clean + out) = *(dirty + i);
out++;
}
norm = geoJSONuncomma (dirty, i_type, n_type);
len = strlen (norm);
for (i = 0; i < len; i++)
{
/* type */
*(clean + out) = *(norm + i);
out++;
}
free (norm);
*(clean + out) = ',';
out++;
if (i_crs >= 0)
{
norm = geoJSONuncomma (dirty, i_crs, n_crs);
len = strlen (norm);
for (i = 0; i < len; i++)
{
/* crs */
*(clean + out) = *(norm + i);
out++;
}
free (norm);
*(clean + out) = ',';
out++;
}
if (i_bbox >= 0)
{
norm = geoJSONuncomma (dirty, i_bbox, n_bbox);
len = strlen (norm);
for (i = 0; i < len; i++)
{
/* bbox */
*(clean + out) = *(norm + i);
out++;
}
free (norm);
*(clean + out) = ',';
out++;
}
norm = geoJSONuncomma (dirty, i_coordinates, n_coordinates);
len = strlen (norm);
for (i = 0; i < len; i++)
{
/* coordinates */
*(clean + out) = *(norm + i);
out++;
}
free (norm);
*(clean + out) = '}';
out++;
*(clean + out) = '\0';
return clean;
}
gaiaGeomCollPtr
gaiaParseGeoJSON (const unsigned char *dirty_buffer)
{
void *pParser = ParseAlloc (malloc);
/* Linked-list of token values */
geoJsonFlexToken *tokens = malloc (sizeof (geoJsonFlexToken));
/* Pointer to the head of the list */
geoJsonFlexToken *head = tokens;
int yv;
yyscan_t scanner;
struct geoJson_data str_data;
char *normalized_buffer = geoJSONnormalize ((const char *) dirty_buffer);
/* initializing the helper structs */
str_data.geoJson_line = 1;
str_data.geoJson_col = 1;
str_data.geoJson_parse_error = 0;
str_data.geoJson_first_dyn_block = NULL;
str_data.geoJson_last_dyn_block = NULL;
str_data.result = NULL;
/* initializing the scanner state */
GeoJsonlex_init_extra (&str_data, &scanner);
tokens->Next = NULL;
GeoJson_scan_string ((char *) normalized_buffer, scanner);
/*
/ Keep tokenizing until we reach the end
/ yylex() will return the next matching Token for us.
*/
while ((yv = yylex (scanner)) != 0)
{
if (yv == -1)
{
str_data.geoJson_parse_error = 1;
break;
}
tokens->Next = malloc (sizeof (geoJsonFlexToken));
tokens->Next->Next = NULL;
tokens->Next->value = str_data.GeoJsonLval.dval;
/* Pass the token to the wkt parser created from lemon */
Parse (pParser, yv, &(tokens->Next->value), &str_data);
tokens = tokens->Next;
}
/* This denotes the end of a line as well as the end of the parser */
Parse (pParser, GEOJSON_NEWLINE, 0, &str_data);
ParseFree (pParser, free);
GeoJsonlex_destroy (scanner);
free (normalized_buffer);
/* Assigning the token as the end to avoid seg faults while cleaning */
tokens->Next = NULL;
geoJSON_cleanup (head);
if (str_data.geoJson_parse_error)
{
if (str_data.result)
{
/* if a Geometry-result has been produced, the stack is already cleaned */
gaiaFreeGeomColl (str_data.result);
geoJsonCleanMapDynAlloc (&str_data, 0);
}
else
{
/* otherwise we are required to clean the stack */
geoJsonCleanMapDynAlloc (&str_data, 1);
}
return NULL;
}
geoJsonCleanMapDynAlloc (&str_data, 0);
if (str_data.result == NULL)
return NULL;
if (!geoJsonCheckValidity (str_data.result))
{
gaiaFreeGeomColl (str_data.result);
return NULL;
}
gaiaMbrGeometry (str_data.result);
return str_data.result;
}
/*
** CAVEAT: we must now undefine any Lemon/Flex own macro
*/
#undef YYNOCODE
#undef YYNSTATE
#undef YYNRULE
#undef YY_SHIFT_MAX
#undef YY_SHIFT_USE_DFLT
#undef YY_REDUCE_USE_DFLT
#undef YY_REDUCE_MAX
#undef YY_FLUSH_BUFFER
#undef YY_DO_BEFORE_ACTION
#undef YY_NUM_RULES
#undef YY_END_OF_BUFFER
#undef YY_END_FILE
#undef YYACTIONTYPE
#undef YY_SZ_ACTTAB
#undef YY_NEW_FILE
#undef BEGIN
#undef YY_START
#undef YY_CURRENT_BUFFER
#undef YY_CURRENT_BUFFER_LVALUE
#undef YY_STATE_BUF_SIZE
#undef YY_DECL
#undef YY_FATAL_ERROR
#undef YYMINORTYPE
#undef YY_CHAR
#undef YYSTYPE
#undef input
#undef ParseAlloc
#undef ParseFree
#undef ParseStackPeak
#undef Parse
#undef yyalloc
#undef yyfree
#undef yyin
#undef yyleng
#undef yyless
#undef yylex
#undef yylineno
#undef yyout
#undef yyrealloc
#undef yyrestart
#undef yyStackEntry
#undef yytext
#undef yywrap
#undef yyzerominor
#undef yy_accept
#undef yy_action
#undef yy_base
#undef yy_buffer_stack
#undef yy_buffer_stack_max
#undef yy_buffer_stack_top
#undef yy_c_buf_p
#undef yy_chk
#undef yy_create_buffer
#undef yy_def
#undef yy_default
#undef yy_delete_buffer
#undef yy_destructor
#undef yy_ec
#undef yy_fatal_error
#undef yy_find_reduce_action
#undef yy_find_shift_action
#undef yy_flex_debug
#undef yy_flush_buffer
#undef yy_get_next_buffer
#undef yy_get_previous_state
#undef yy_init
#undef yy_init_buffer
#undef yy_init_globals
#undef yy_load_buffer
#undef yy_load_buffer_state
#undef yy_lookahead
#undef yy_meta
#undef yy_new_buffer
#undef yy_nxt
#undef yy_parse_failed
#undef yy_pop_parser_stack
#undef yy_reduce
#undef yy_reduce_ofst
#undef yy_set_bol
#undef yy_set_interactive
#undef yy_shift
#undef yy_shift_ofst
#undef yy_start
#undef yy_state_type
#undef yy_switch_to_buffer
#undef yy_syntax_error
#undef yy_trans_info
#undef yy_try_NUL_trans
#undef yyParser
#undef yyStackEntry
#undef yyStackOverflow
#undef yyRuleInfo
#undef yytext_ptr
#undef yyunput
#undef yyzerominor
#undef ParseARG_SDECL
#undef ParseARG_PDECL
#undef ParseARG_FETCH
#undef ParseARG_STORE
#undef REJECT
#undef yymore
#undef YY_MORE_ADJ
#undef YY_RESTORE_YY_MORE_OFFSET
#undef YY_LESS_LINENO
#undef yyTracePrompt
#undef yyTraceFILE
#undef yyTokenName
#undef yyRuleName
#undef ParseTrace
#undef yylex
#undef YY_DECL
libspatialite-5.1.0/src/gaiageo/gg_kml.c 0000644 0001750 0001750 00000134102 14463127014 015056 0000000 0000000 /*
gg_kml.c -- KML parser/lexer
version 5.1.0, 2023 August 4
Author: Sandro Furieri a.furieri@lqt.it
------------------------------------------------------------------------------
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the SpatiaLite library
The Initial Developer of the Original Code is Alessandro Furieri
Portions created by the Initial Developer are Copyright (C) 2011-2023
the Initial Developer. All Rights Reserved.
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include
#include
#include
#if defined(_WIN32) || defined(WIN32)
#include
#ifndef isatty
#define isatty _isatty
#endif
#ifndef fileno
#define fileno _fileno
#endif
#endif
#define KML_PARSER_OPEN_NODE 1
#define KML_PARSER_SELF_CLOSED_NODE 2
#define KML_PARSER_CLOSED_NODE 3
#define GAIA_KML_UNKNOWN 0
#define GAIA_KML_POINT 1
#define GAIA_KML_LINESTRING 2
#define GAIA_KML_POLYGON 3
#define GAIA_KML_MULTIGEOMETRY 4
#define KML_DYN_NONE 0
#define KML_DYN_DYNLINE 1
#define KML_DYN_GEOM 2
#define KML_DYN_DYNPG 3
#define KML_DYN_NODE 4
#define KML_DYN_COORD 5
#define KML_DYN_ATTRIB 6
#define KML_DYN_BLOCK 1024
/*
** CAVEAT: we must redefine any Lemon/Flex own macro
*/
#define YYMINORTYPE KML_MINORTYPE
#define YY_CHAR KML_YY_CHAR
#define input kml_input
#define ParseAlloc kmlParseAlloc
#define ParseFree kmlParseFree
#define ParseStackPeak kmlParseStackPeak
#define Parse kmlParse
#define yyStackEntry kml_yyStackEntry
#define yyzerominor kml_yyzerominor
#define yy_accept kml_yy_accept
#define yy_action kml_yy_action
#define yy_base kml_yy_base
#define yy_buffer_stack kml_yy_buffer_stack
#define yy_buffer_stack_max kml_yy_buffer_stack_max
#define yy_buffer_stack_top kml_yy_buffer_stack_top
#define yy_c_buf_p kml_yy_c_buf_p
#define yy_chk kml_yy_chk
#define yy_def kml_yy_def
#define yy_default kml_yy_default
#define yy_destructor kml_yy_destructor
#define yy_ec kml_yy_ec
#define yy_fatal_error kml_yy_fatal_error
#define yy_find_reduce_action kml_yy_find_reduce_action
#define yy_find_shift_action kml_yy_find_shift_action
#define yy_get_next_buffer kml_yy_get_next_buffer
#define yy_get_previous_state kml_yy_get_previous_state
#define yy_init kml_yy_init
#define yy_init_globals kml_yy_init_globals
#define yy_lookahead kml_yy_lookahead
#define yy_meta kml_yy_meta
#define yy_nxt kml_yy_nxt
#define yy_parse_failed kml_yy_parse_failed
#define yy_pop_parser_stack kml_yy_pop_parser_stack
#define yy_reduce kml_yy_reduce
#define yy_reduce_ofst kml_yy_reduce_ofst
#define yy_shift kml_yy_shift
#define yy_shift_ofst kml_yy_shift_ofst
#define yy_start kml_yy_start
#define yy_state_type kml_yy_state_type
#define yy_syntax_error kml_yy_syntax_error
#define yy_trans_info kml_yy_trans_info
#define yy_try_NUL_trans kml_yy_try_NUL_trans
#define yyParser kml_yyParser
#define yyStackEntry kml_yyStackEntry
#define yyStackOverflow kml_yyStackOverflow
#define yyRuleInfo kml_yyRuleInfo
#define yyunput kml_yyunput
#define yyzerominor kml_yyzerominor
#define yyTraceFILE kml_yyTraceFILE
#define yyTracePrompt kml_yyTracePrompt
#define yyTokenName kml_yyTokenName
#define yyRuleName kml_yyRuleName
#define ParseTrace kml_ParseTrace
#define yylex kml_yylex
#define YY_DECL int yylex (yyscan_t yyscanner)
/* including LEMON generated header */
#include "Kml.h"
typedef union
{
char *pval;
struct symtab *symp;
} kml_yystype;
#define YYSTYPE kml_yystype
/*
** This is a linked-list struct to store all the values for each token.
*/
typedef struct kmlFlexTokenStruct
{
char *value;
struct kmlFlexTokenStruct *Next;
} kmlFlexToken;
typedef struct kml_coord
{
char *Value;
struct kml_coord *Next;
} kmlCoord;
typedef kmlCoord *kmlCoordPtr;
typedef struct kml_attr
{
char *Key;
char *Value;
struct kml_attr *Next;
} kmlAttr;
typedef kmlAttr *kmlAttrPtr;
typedef struct kml_node
{
char *Tag;
int Type;
int Error;
struct kml_attr *Attributes;
struct kml_coord *Coordinates;
struct kml_node *Next;
} kmlNode;
typedef kmlNode *kmlNodePtr;
typedef struct kml_dynamic_ring
{
gaiaDynamicLinePtr ring;
int interior;
int has_z;
struct kml_dynamic_ring *next;
} kmlDynamicRing;
typedef kmlDynamicRing *kmlDynamicRingPtr;
typedef struct kml_dynamic_polygon
{
struct kml_dynamic_ring *first;
struct kml_dynamic_ring *last;
} kmlDynamicPolygon;
typedef kmlDynamicPolygon *kmlDynamicPolygonPtr;
struct kml_dyn_block
{
/* a struct taking trace of dynamic allocations */
int type[KML_DYN_BLOCK];
void *ptr[KML_DYN_BLOCK];
int index;
struct kml_dyn_block *next;
};
struct kml_data
{
/* a struct used to make the lexer-parser reentrant and thread-safe */
int kml_parse_error;
int kml_line;
int kml_col;
struct kml_dyn_block *kml_first_dyn_block;
struct kml_dyn_block *kml_last_dyn_block;
kmlNodePtr result;
YYSTYPE KmlLval;
};
static struct kml_dyn_block *
kmlCreateDynBlock (void)
{
/* allocating a new block to trace dynamic allocations */
int i;
struct kml_dyn_block *p = malloc (sizeof (struct kml_dyn_block));
for (i = 0; i < KML_DYN_BLOCK; i++)
{
/* initializing map entries */
p->type[i] = KML_DYN_NONE;
p->ptr[i] = NULL;
}
p->index = 0;
p->next = NULL;
return p;
}
static void
kmlMapDynAlloc (struct kml_data *p_data, int type, void *ptr)
{
/* appending a dynamic allocation into the map */
struct kml_dyn_block *p;
if (p_data->kml_first_dyn_block == NULL)
{
/* inserting the first block of the map */
p = kmlCreateDynBlock ();
p_data->kml_first_dyn_block = p;
p_data->kml_last_dyn_block = p;
}
if (p_data->kml_last_dyn_block->index >= KML_DYN_BLOCK)
{
/* adding a further block to the map */
p = kmlCreateDynBlock ();
p_data->kml_last_dyn_block->next = p;
p_data->kml_last_dyn_block = p;
}
p_data->kml_last_dyn_block->type[p_data->kml_last_dyn_block->index] = type;
p_data->kml_last_dyn_block->ptr[p_data->kml_last_dyn_block->index] = ptr;
p_data->kml_last_dyn_block->index++;
}
static void
kmlMapDynClean (struct kml_data *p_data, void *ptr)
{
/* deleting a dynamic allocation from the map */
int i;
struct kml_dyn_block *p = p_data->kml_first_dyn_block;
while (p)
{
for (i = 0; i < KML_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case KML_DYN_DYNLINE:
case KML_DYN_GEOM:
case KML_DYN_DYNPG:
case KML_DYN_NODE:
case KML_DYN_COORD:
case KML_DYN_ATTRIB:
if (p->ptr[i] == ptr)
{
p->type[i] = KML_DYN_NONE;
return;
}
break;
};
}
p = p->next;
}
}
static void
kml_free_dyn_polygon (kmlDynamicPolygonPtr dyn)
{
/* deleting a dynamic polygon (ring collection) */
kmlDynamicRingPtr r;
kmlDynamicRingPtr rn;
if (!dyn)
return;
r = dyn->first;
while (r)
{
rn = r->next;
if (r->ring)
gaiaFreeDynamicLine (r->ring);
free (r);
r = rn;
}
free (dyn);
}
static void
kml_free_coord (kmlCoordPtr c)
{
/* deleting a KML coordinate */
if (c == NULL)
return;
if (c->Value)
free (c->Value);
free (c);
}
static void
kml_free_attrib (kmlAttrPtr a)
{
/* deleting a KML attribute */
if (a == NULL)
return;
if (a->Key)
free (a->Key);
if (a->Value)
free (a->Value);
free (a);
}
static void
kml_free_node (kmlNodePtr n)
{
/* deleting a KML node */
kmlAttrPtr a;
kmlAttrPtr an;
kmlCoordPtr c;
kmlCoordPtr cn;
if (n == NULL)
return;
a = n->Attributes;
while (a)
{
an = a->Next;
kml_free_attrib (a);
a = an;
}
c = n->Coordinates;
while (c)
{
cn = c->Next;
kml_free_coord (c);
c = cn;
}
if (n->Tag)
free (n->Tag);
free (n);
}
static void
kmlCleanMapDynAlloc (struct kml_data *p_data, int clean_all)
{
/* cleaning the dynamic allocations map */
int i;
struct kml_dyn_block *pn;
struct kml_dyn_block *p = p_data->kml_first_dyn_block;
while (p)
{
if (clean_all)
{
for (i = 0; i < KML_DYN_BLOCK; i++)
{
/* deleting Geometry objects */
switch (p->type[i])
{
case KML_DYN_DYNLINE:
gaiaFreeDynamicLine ((gaiaDynamicLinePtr)
(p->ptr[i]));
break;
case KML_DYN_GEOM:
gaiaFreeGeomColl ((gaiaGeomCollPtr) (p->ptr[i]));
break;
case KML_DYN_DYNPG:
kml_free_dyn_polygon ((kmlDynamicPolygonPtr)
(p->ptr[i]));
break;
case KML_DYN_NODE:
kml_free_node ((kmlNodePtr) (p->ptr[i]));
break;
case KML_DYN_COORD:
kml_free_coord ((kmlCoordPtr) (p->ptr[i]));
break;
case KML_DYN_ATTRIB:
kml_free_attrib ((kmlAttrPtr) (p->ptr[i]));
break;
};
}
}
/* deleting the map block */
pn = p->next;
free (p);
p = pn;
}
}
static kmlDynamicPolygonPtr
kml_alloc_dyn_polygon (struct kml_data *p_data)
{
/* creating a dynamic polygon (ring collection) */
kmlDynamicPolygonPtr p = malloc (sizeof (kmlDynamicPolygon));
kmlMapDynAlloc (p_data, KML_DYN_DYNPG, p);
p->first = NULL;
p->last = NULL;
return p;
}
static void
kml_add_polygon_ring (kmlDynamicPolygonPtr dyn_pg, gaiaDynamicLinePtr dyn,
int interior, int has_z)
{
/* inserting a further ring into the collection (dynamic polygon) */
kmlDynamicRingPtr p = malloc (sizeof (kmlDynamicRing));
p->ring = dyn;
p->interior = interior;
p->has_z = has_z;
p->next = NULL;
if (dyn_pg->first == NULL)
dyn_pg->first = p;
if (dyn_pg->last != NULL)
dyn_pg->last->next = p;
dyn_pg->last = p;
}
static void
kml_freeString (char **ptr)
{
/* releasing a string from the lexer */
if (*ptr != NULL)
free (*ptr);
*ptr = NULL;
}
static void
kml_saveString (char **ptr, const char *str)
{
/* saving a string from the lexer */
int len = strlen (str);
kml_freeString (ptr);
*ptr = malloc (len + 1);
strcpy (*ptr, str);
}
static kmlCoordPtr
kml_coord (struct kml_data *p_data, void *value)
{
/* creating a coord Item */
int len;
kmlFlexToken *tok = (kmlFlexToken *) value;
kmlCoordPtr c = malloc (sizeof (kmlCoord));
kmlMapDynAlloc (p_data, KML_DYN_COORD, c);
len = strlen (tok->value);
c->Value = malloc (len + 1);
strcpy (c->Value, tok->value);
c->Next = NULL;
return c;
}
static kmlAttrPtr
kml_attribute (struct kml_data *p_data, void *key, void *value)
{
/* creating an attribute */
int len;
kmlFlexToken *k_tok = (kmlFlexToken *) key;
kmlFlexToken *v_tok = (kmlFlexToken *) value;
kmlAttrPtr a = malloc (sizeof (kmlAttr));
kmlMapDynAlloc (p_data, KML_DYN_ATTRIB, a);
len = strlen (k_tok->value);
a->Key = malloc (len + 1);
strcpy (a->Key, k_tok->value);
len = strlen (v_tok->value);
/* we need to de-quote the string, removing first and last ".." */
if (*(v_tok->value + 0) == '"' && *(v_tok->value + len - 1) == '"')
{
a->Value = malloc (len - 1);
memcpy (a->Value, v_tok->value + 1, len - 1);
*(a->Value + len - 1) = '\0';
}
else
{
a->Value = malloc (len + 1);
strcpy (a->Value, v_tok->value);
}
a->Next = NULL;
return a;
}
static void
kml_freeTree (kmlNodePtr t)
{
/* deleting a KML tree */
kmlNodePtr n;
kmlNodePtr nn;
n = t;
while (n)
{
nn = n->Next;
kml_free_node (n);
n = nn;
}
}
static kmlNodePtr
kml_createNode (struct kml_data *p_data, void *tag, void *attributes,
void *coords)
{
/* creating a node */
kmlAttrPtr a;
kmlCoordPtr c;
int len;
kmlFlexToken *tok = (kmlFlexToken *) tag;
kmlNodePtr n = malloc (sizeof (kmlNode));
kmlMapDynAlloc (p_data, KML_DYN_NODE, n);
len = strlen (tok->value);
n->Tag = malloc (len + 1);
strcpy (n->Tag, tok->value);
n->Type = KML_PARSER_OPEN_NODE;
n->Error = 0;
a = (kmlAttrPtr) attributes;
while (a)
{
/* transferring ownership of attributes */
kmlMapDynClean (p_data, a);
a = a->Next;
}
n->Attributes = attributes;
c = (kmlCoordPtr) coords;
while (c)
{
/* transferring ownership of attributes */
kmlMapDynClean (p_data, c);
c = c->Next;
}
n->Coordinates = coords;
n->Next = NULL;
return n;
}
static kmlNodePtr
kml_createSelfClosedNode (struct kml_data *p_data, void *tag, void *attributes)
{
/* creating a self-closed node */
kmlAttrPtr a;
int len;
kmlFlexToken *tok = (kmlFlexToken *) tag;
kmlNodePtr n = malloc (sizeof (kmlNode));
kmlMapDynAlloc (p_data, KML_DYN_NODE, n);
len = strlen (tok->value);
n->Tag = malloc (len + 1);
strcpy (n->Tag, tok->value);
n->Type = KML_PARSER_SELF_CLOSED_NODE;
n->Error = 0;
a = (kmlAttrPtr) attributes;
while (a)
{
/* transferring ownership of attributes */
kmlMapDynClean (p_data, a);
a = a->Next;
}
n->Attributes = attributes;
n->Coordinates = NULL;
n->Next = NULL;
return n;
}
static kmlNodePtr
kml_closingNode (struct kml_data *p_data, void *tag)
{
/* creating a closing node */
int len;
kmlFlexToken *tok = (kmlFlexToken *) tag;
kmlNodePtr n = malloc (sizeof (kmlNode));
kmlMapDynAlloc (p_data, KML_DYN_NODE, n);
len = strlen (tok->value);
n->Tag = malloc (len + 1);
strcpy (n->Tag, tok->value);
n->Type = KML_PARSER_CLOSED_NODE;
n->Error = 0;
n->Attributes = NULL;
n->Coordinates = NULL;
n->Next = NULL;
return n;
}
static int
kml_cleanup (kmlFlexToken * token)
{
kmlFlexToken *ptok;
kmlFlexToken *ptok_n;
if (token == NULL)
return 0;
ptok = token;
while (ptok)
{
ptok_n = ptok->Next;
if (ptok->value != NULL)
free (ptok->value);
free (ptok);
ptok = ptok_n;
}
return 0;
}
static void
kml_xferString (char **p, const char *str)
{
/* saving some token */
int len;
if (str == NULL)
{
*p = NULL;
return;
}
len = strlen (str);
*p = malloc (len + 1);
strcpy (*p, str);
}
static int
guessKmlGeometryType (kmlNodePtr node)
{
/* attempting to guess the Geometry Type for a KML node */
int type = GAIA_KML_UNKNOWN;
if (strcmp (node->Tag, "Point") == 0)
type = GAIA_KML_POINT;
if (strcmp (node->Tag, "LineString") == 0)
type = GAIA_KML_LINESTRING;
if (strcmp (node->Tag, "Polygon") == 0)
type = GAIA_KML_POLYGON;
if (strcmp (node->Tag, "MultiGeometry") == 0)
type = GAIA_KML_MULTIGEOMETRY;
return type;
}
static int
kml_check_coord (const char *value)
{
/* checking a KML coordinate */
int decimal = 0;
int exp = 0;
int expsign = 0;
const char *p = value;
if (*p == '+' || *p == '-')
p++;
while (*p != '\0')
{
if (*p == '.')
{
if (!decimal)
decimal = 1;
else
return 0;
}
else if (*p >= '0' && *p <= '9')
;
else if (*p == 'e' || *p == 'E')
exp++;
else if (*p == '+' || *p == '-')
{
if (!exp)
return 0;
expsign++;
}
else
return 0;
p++;
}
if (exp > 1 || expsign > 1)
return 0;
return 1;
}
static int
kml_extract_coords (const char *value, double *x, double *y, double *z,
int *count)
{
/* extracting KML coords from a comma-separated string */
const char *in = value;
char buf[1024];
char *out = buf;
*out = '\0';
while (*in != '\0')
{
if (*in == ',')
{
*out = '\0';
if (*buf != '\0')
{
if (!kml_check_coord (buf))
return 0;
switch (*count)
{
case 0:
*x = atof (buf);
*count += 1;
break;
case 1:
*y = atof (buf);
*count += 1;
break;
case 2:
*z = atof (buf);
*count += 1;
break;
default:
*count += 1;
break;
};
}
in++;
out = buf;
*out = '\0';
continue;
}
*out++ = *in++;
}
*out = '\0';
/* parsing the last item */
if (*buf != '\0')
{
if (!kml_check_coord (buf))
return 0;
switch (*count)
{
case 0:
*x = atof (buf);
*count += 1;
break;
case 1:
*y = atof (buf);
*count += 1;
break;
case 2:
*z = atof (buf);
*count += 1;
break;
default:
*count += 1;
break;
};
}
return 1;
}
static int
kml_parse_point_v2 (kmlCoordPtr coord, double *x, double *y, double *z,
int *has_z)
{
/* parsing KML [Point] */
int count = 0;
kmlCoordPtr c = coord;
while (c)
{
if (!kml_extract_coords (c->Value, x, y, z, &count))
return 0;
c = c->Next;
}
if (count == 2)
{
*has_z = 0;
return 1;
}
if (count == 3)
{
*has_z = 1;
return 1;
}
return 0;
}
static int
kml_parse_point (struct kml_data *p_data, gaiaGeomCollPtr geom, kmlNodePtr node,
kmlNodePtr * next)
{
/* parsing a */
double x;
double y;
double z;
int has_z;
gaiaGeomCollPtr pt;
gaiaGeomCollPtr last;
if (strcmp (node->Tag, "coordinates") == 0)
{
/* parsing a KML */
if (!kml_parse_point_v2 (node->Coordinates, &x, &y, &z, &has_z))
return 0;
node = node->Next;
if (node == NULL)
return 0;
if (strcmp (node->Tag, "coordinates") == 0)
;
else
return 0;
node = node->Next;
if (node == NULL)
return 0;
if (strcmp (node->Tag, "Point") == 0)
;
else
return 0;
*next = node->Next;
goto ok;
}
return 0;
ok:
/* ok, KML nodes match as expected */
if (has_z)
{
pt = gaiaAllocGeomCollXYZ ();
kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt);
gaiaAddPointToGeomCollXYZ (pt, x, y, z);
}
else
{
pt = gaiaAllocGeomColl ();
kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt);
gaiaAddPointToGeomColl (pt, x, y);
}
last = geom;
while (1)
{
/* searching the last Geometry within chain */
if (last->Next == NULL)
break;
last = last->Next;
}
last->Next = pt;
return 1;
}
static int
kml_extract_multi_coord (const char *value, double *x, double *y, double *z,
int *count, int *follow)
{
/* extracting KML coords from a comma-separated string */
const char *in = value;
char buf[1024];
char *out = buf;
int last = 0;
*out = '\0';
while (*in != '\0')
{
last = *in;
if (*in == ',')
{
*out = '\0';
if (*buf != '\0')
{
if (!kml_check_coord (buf))
return 0;
switch (*count)
{
case 0:
*x = atof (buf);
*count += 1;
break;
case 1:
*y = atof (buf);
*count += 1;
break;
case 2:
*z = atof (buf);
*count += 1;
break;
default:
*count += 1;
break;
};
}
in++;
out = buf;
*out = '\0';
continue;
}
*out++ = *in++;
}
*out = '\0';
/* parsing the last item */
if (*buf != '\0')
{
if (!kml_check_coord (buf))
return 0;
switch (*count)
{
case 0:
*x = atof (buf);
*count += 1;
break;
case 1:
*y = atof (buf);
*count += 1;
break;
case 2:
*z = atof (buf);
*count += 1;
break;
default:
*count += 1;
break;
};
}
if (last == ',')
*follow = 1;
else
*follow = 0;
return 1;
}
static int
kml_extract_multi_coords (kmlCoordPtr coord, double *x, double *y, double *z,
int *count, kmlCoordPtr * next)
{
/* extracting KML coords from a comma-separated string */
int follow;
kmlCoordPtr c = coord;
while (c)
{
if (!kml_extract_multi_coord (c->Value, x, y, z, count, &follow))
return 0;
if (!follow && c->Next != NULL)
{
if (*(c->Next->Value) == ',')
follow = 1;
}
if (follow)
c = c->Next;
else
{
*next = c->Next;
break;
}
}
return 1;
}
static void
kml_add_point_to_line (gaiaDynamicLinePtr dyn, double x, double y)
{
/* appending a point */
gaiaAppendPointToDynamicLine (dyn, x, y);
}
static void
kml_add_point_to_lineZ (gaiaDynamicLinePtr dyn, double x, double y, double z)
{
/* appending a point */
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
}
static int
kml_parse_coordinates (kmlCoordPtr coord, gaiaDynamicLinePtr dyn, int *has_z)
{
/* parsing KML [Linestring or Ring] */
int count = 0;
double x;
double y;
double z;
kmlCoordPtr next = NULL;
kmlCoordPtr c = coord;
while (c)
{
if (!kml_extract_multi_coords (c, &x, &y, &z, &count, &next))
return 0;
if (count == 2)
{
*has_z = 0;
kml_add_point_to_line (dyn, x, y);
count = 0;
}
else if (count == 3)
{
kml_add_point_to_lineZ (dyn, x, y, z);
count = 0;
}
else
return 0;
c = next;
}
return 1;
}
static int
kml_count_dyn_points (gaiaDynamicLinePtr dyn)
{
/* count how many vertices are into sone linestring/ring */
int iv = 0;
gaiaPointPtr pt = dyn->First;
while (pt)
{
iv++;
pt = pt->Next;
}
return iv;
}
static int
kml_parse_linestring (struct kml_data *p_data, gaiaGeomCollPtr geom,
kmlNodePtr node, kmlNodePtr * next)
{
/* parsing a */
gaiaGeomCollPtr ln;
gaiaGeomCollPtr last;
gaiaLinestringPtr new_ln;
gaiaPointPtr pt;
int iv;
int has_z = 1;
int points = 0;
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
kmlMapDynAlloc (p_data, KML_DYN_DYNLINE, dyn);
if (strcmp (node->Tag, "coordinates") == 0)
{
/* parsing a KML */
if (!kml_parse_coordinates (node->Coordinates, dyn, &has_z))
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "coordinates") == 0)
;
else
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "LineString") == 0)
;
else
goto error;
*next = node->Next;
}
/* ok, KML nodes match as expected */
points = kml_count_dyn_points (dyn);
if (points < 2)
goto error;
if (has_z)
{
ln = gaiaAllocGeomCollXYZ ();
kmlMapDynAlloc (p_data, KML_DYN_GEOM, ln);
new_ln = gaiaAddLinestringToGeomColl (ln, points);
pt = dyn->First;
iv = 0;
while (pt)
{
gaiaSetPointXYZ (new_ln->Coords, iv, pt->X, pt->Y, pt->Z);
iv++;
pt = pt->Next;
}
}
else
{
ln = gaiaAllocGeomColl ();
kmlMapDynAlloc (p_data, KML_DYN_GEOM, ln);
new_ln = gaiaAddLinestringToGeomColl (ln, points);
pt = dyn->First;
iv = 0;
while (pt)
{
gaiaSetPoint (new_ln->Coords, iv, pt->X, pt->Y);
iv++;
pt = pt->Next;
}
}
last = geom;
while (1)
{
/* searching the last Geometry within chain */
if (last->Next == NULL)
break;
last = last->Next;
}
last->Next = ln;
gaiaFreeDynamicLine (dyn);
return 1;
error:
gaiaFreeDynamicLine (dyn);
return 0;
}
static gaiaDynamicLinePtr
kml_parse_ring (kmlNodePtr node, int *interior, int *has_z, kmlNodePtr * next)
{
/* parsing a generic KML ring */
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
*has_z = 1;
if (strcmp (node->Tag, "outerBoundaryIs") == 0)
{
/* parsing a KML */
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "LinearRing") == 0)
;
else
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "coordinates") == 0)
{
/* parsing a KML */
if (!kml_parse_coordinates (node->Coordinates, dyn, has_z))
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "coordinates") == 0)
;
else
goto error;
}
else
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "LinearRing") == 0)
;
else
goto error;
node = node->Next;
if (node == NULL)
goto error;
if (strcmp (node->Tag, "outerBoundaryIs") == 0)
;
else
goto error;
*interior = 0;
*next = node->Next;
return dyn;
}
if (strcmp (node->Tag, "innerBoundaryIs") == 0)
{
/* parsing a KML