pax_global_header 0000666 0000000 0000000 00000000064 14653160677 0014531 g ustar 00root root 0000000 0000000 52 comment=6d31ab83c86162bf77b8a1bead57d177cda1c2ea
mapcache-rel-1-14-1/ 0000775 0000000 0000000 00000000000 14653160677 0014134 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/.github/ 0000775 0000000 0000000 00000000000 14653160677 0015474 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/.github/FUNDING.yml 0000664 0000000 0000000 00000000243 14653160677 0017310 0 ustar 00root root 0000000 0000000 # point to OSGeo sponsor page
github: [OSGeo]
# point to PayPal directly
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MS7JAL9R268D2 mapcache-rel-1-14-1/.github/workflows/ 0000775 0000000 0000000 00000000000 14653160677 0017531 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/.github/workflows/backport.yml 0000664 0000000 0000000 00000001013 14653160677 0022054 0 ustar 00root root 0000000 0000000 name: Backport
on:
pull_request_target:
types:
- closed
- labeled
jobs:
backport:
runs-on: ubuntu-latest
name: Backport
steps:
- name: Backport Bot
id: backport
if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( join( github.event.pull_request.labels.*.name ), 'backport') ) || contains( github.event.label.name, 'backport' ) )
uses: m-kuhn/backport@v1.2.7
with:
github_token: ${{ secrets.GITHUB_TOKEN }} mapcache-rel-1-14-1/.github/workflows/build-linux.yml 0000664 0000000 0000000 00000005201 14653160677 0022506 0 ustar 00root root 0000000 0000000 name: Build MapCache on Linux
on: [ push, pull_request ]
jobs:
build-matrix:
strategy:
matrix:
os: [ ubuntu-20.04 ]
option: [ minimal, default, maximal ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
if [[ 'minimal,default,maximal' =~ ${{ matrix.option }} ]]
then
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y libcurl4-openssl-dev apache2-dev
fi
if [[ 'default,maximal' =~ ${{ matrix.option }} ]]
then
sudo apt-get install -y libgdal-dev libfcgi-dev libpixman-1-dev
sudo apt-get install -y gdal-bin libxml2-utils
fi
if [[ 'maximal' =~ ${{ matrix.option }} ]]
then
sudo apt-get install -y libhiredis-dev libdb-dev libmapserver-dev libpcre2-dev
fi
- name: Build MapCache
run: |
if [[ 'minimal' == ${{ matrix.option }} ]]
then
options="-DWITH_SQLITE=OFF \
-DWITH_PIXMAN=OFF \
-DWITH_GDAL=OFF \
-DWITH_APACHE=OFF \
-DWITH_CGI=OFF \
-DWITH_OGR=OFF \
-DWITH_GEOS=OFF \
-DWITH_MAPCACHE_DETAIL=OFF"
elif [[ 'default' == ${{ matrix.option }} ]]
then
options=""
elif [[ 'maximal' == ${{ matrix.option }} ]]
then
options="-DWITH_POSTGRESQL=ON \
-DWITH_BERKELEY_DB=ON \
-DWITH_MEMCACHE=ON \
-DWITH_REDIS=ON \
-DWITH_TIFF=ON \
-DWITH_TIFF_WRITE_SUPPORT=ON \
-DWITH_GEOTIFF=ON \
-DWITH_PCRE=OFF \
-DWITH_PCRE2=ON \
-DWITH_MAPSERVER=ON \
-DWITH_RIAK=OFF"
fi
mkdir build
cd build
cmake ${options} ${{ github.workspace }}
make
sudo make install
sudo ldconfig
- name: Run tests
run: |
if [[ 'ubuntu-20.04' == ${{ matrix.os }} ]] \
&& [[ 'default' == ${{ matrix.option }} ]]
then
cd ${{ github.workspace }}/tests
./setup.sh
./run.sh
else
echo No test performed on this target
fi
mapcache-rel-1-14-1/.github/workflows/build-windows.yml 0000664 0000000 0000000 00000013103 14653160677 0023041 0 ustar 00root root 0000000 0000000 name: Build MapCache on Windows
on: [ push, pull_request ]
jobs:
build-matrix:
strategy:
matrix:
os: [ windows-2019 ]
option: [ default ]
runs-on: ${{matrix.os}}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
Set-Location -Path "${{github.workspace}}"
New-Item -Path . -Name "sdk" -ItemType "directory"
Set-Location -Path "sdk"
curl -O https://download.gisinternals.com/sdk/downloads/release-1928-x64-dev.zip
unzip -qq release-1928-x64-dev.zip
$sdkprefix = "${{github.workspace}}\sdk\release-1928-x64"
Set-Location -Path "$sdkprefix\lib"
Copy-Item -Path "libfcgi.lib" -Destination "fcgi.lib"
Copy-Item -Path "apr-1.lib" -Destination "apr-1-1.lib"
Copy-Item -Path "libapr-1.lib" -Destination "apr-1.lib"
Copy-Item -Path "aprutil-1.lib" -Destination "aprutil-1-1.lib"
Copy-Item -Path "libaprutil-1.lib" -Destination "aprutil-1.lib"
- name: Build MapCache
run: |
$sdkprefix = "${{github.workspace}}\sdk\release-1928-x64"
Set-Location -Path "${{github.workspace}}"
New-Item -Path . -Name "build" -ItemType "directory"
Set-Location -Path "build"
cmake -DCMAKE_PREFIX_PATH="$sdkprefix" -DWITH_APACHE=OFF -DWITH_FCGI=ON -DWITH_PCRE=ON -DWITH_TIFF=OFF "${{github.workspace}}"
cmake --build . --config Release
Copy-Item -Destination "$sdkprefix\bin" -Path "Release\mapcache.dll", "cgi\Release\mapcache.fcgi.exe", "util\Release\mapcache_seed.exe", "contrib\mapcache_detail\Release\mapcache_detail.exe"
Set-Location -Path "$sdkprefix\bin"
Compress-Archive -DestinationPath "${{github.workspace}}\mapcache.zip" -Path "${{github.workspace}}\mapcache.xml", "mapcache.dll", "mapcache.fcgi.exe", "mapcache_seed.exe", "mapcache_detail.exe"
- name: Upload binary artifacts
uses: actions/upload-artifact@v2
with:
name: binaries
path: mapcache.zip
retention-days: 15
- name: Setup tests
run: |
$sdkprefix = "${{github.workspace}}\sdk\release-1928-x64"
Set-Location -Path "${{github.workspace}}\build"
Copy-Item -Path "..\tests\data\world.tif" -Destination .
New-Item -Path "mapcache.xml"
Set-Content -Path "mapcache.xml" -Value @"
${{github.workspace}}\build\world.tif
${{github.workspace}}\build
disk
global-tif
GoogleMapsCompatible
JPEG
1 1
${{github.workspace}}\build
debug
"@
- name: Run tests
run: |
$sdkprefix = "${{github.workspace}}\sdk\release-1928-x64"
Set-Location -Path "$sdkprefix\bin"
$env:GDAL_DATA = "$sdkprefix\bin\gdal-data"
$env:PROJ_LIB = "$sdkprefix\bin\proj9\share"
.\mapcache_seed.exe -c "${{github.workspace}}\build\mapcache.xml" -t global --force -z 0,1
Copy-Item -Path "${{github.workspace}}\build\global\GoogleMapsCompatible\00\000\000\000\000\000\000.jpg" -Destination "${{github.workspace}}\seed.jpg"
.\gdal\apps\gdalinfo.exe -checksum "${{github.workspace}}\seed.jpg"
$match = (.\gdal\apps\gdalinfo.exe -checksum "${{github.workspace}}\seed.jpg" | Select-String -CaseSensitive -Pattern "Checksum=21411" -Quiet)
if ( $match ) {
"Success: matched checksum for seed.jpg"
} else {
"Failure: Did not get expected checksum for seed.jpg"
exit 1
}
$env:MAPCACHE_CONFIG_FILE = "${{github.workspace}}\build\mapcache.xml"
$env:REQUEST_METHOD = "GET"
$env:PATH_INFO = "/wmts/1.0.0/global/default/GoogleMapsCompatible/0/0/0.jpg"
$env:QUERY_STRING = ""
Start-Process -FilePath ".\mapcache.fcgi.exe" -RedirectStandardOutput "${{github.workspace}}\fcgi.jpg" -NoNewWindow -Wait
perl.exe -0777 -pi -e 'binmode ARGV;binmode ARGVOUT;s/[A-Z][a-z][-:; ,\/=A-Za-z0-9\r\n]*//' "${{github.workspace}}\fcgi.jpg"
.\gdal\apps\gdalinfo.exe -checksum "${{github.workspace}}\fcgi.jpg"
$match = (.\gdal\apps\gdalinfo.exe -checksum "${{github.workspace}}\fcgi.jpg" | Select-String -CaseSensitive -Pattern "Checksum=21411" -Quiet)
if ( $match ) {
"Success: matched checksum for fcgi.jpg"
} else {
"Failure: Did not get expected checksum for fcgi.jpg"
exit 1
}
- name: Upload test artifacts
uses: actions/upload-artifact@v2
with:
name: test-results
path: |
seed.jpg
fcgi.jpg
retention-days: 2
mapcache-rel-1-14-1/.github/workflows/check-crlf.yml 0000664 0000000 0000000 00000000754 14653160677 0022263 0 ustar 00root root 0000000 0000000 # check for Windows CRLF in files
# homepage: https://github.com/marketplace/actions/check-crlf
name: Check CRLF
on: [push, pull_request]
jobs:
Check-CRLF:
name: verify that only LF linefeeds are used
runs-on: ubuntu-18.04
steps:
- name: Checkout repository contents
uses: actions/checkout@v1
- name: Use action to check for CRLF endings
uses: erclu/check-crlf@v1.1.2
with: # ignore directories below, space-delimited
exclude: mapcache-rel-1-14-1/.github/workflows/irc_notify.yml 0000664 0000000 0000000 00000002673 14653160677 0022431 0 ustar 00root root 0000000 0000000 # send build notifications to the #mapcache IRC channel
# homepage: https://github.com/marketplace/actions/notify-irc
name: "IRC Push Notification"
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
irc_notify:
runs-on: ubuntu-latest
#if: github.repository == 'MapServer/mapcache'
steps:
- name: irc push
uses: rectalogic/notify-irc@v1
if: github.event_name == 'push'
with:
channel: "#mapcache"
server: "irc.libera.chat"
nickname: mapcache-github-notifier
message: |
${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }}
${{ join(github.event.commits.*.message) }}
- name: irc pull request
uses: rectalogic/notify-irc@v1
if: github.event_name == 'pull_request'
with:
channel: "#mapcache"
server: "irc.libera.chat"
nickname: mapcache-github-notifier
message: |
${{ github.actor }} opened PR ${{ github.event.pull_request.html_url }}
- name: irc tag created
uses: rectalogic/notify-irc@v1
if: github.event_name == 'create' && github.event.ref_type == 'tag'
with:
channel: "#mapcache"
server: "irc.libera.chat"
nickname: mapcache-github-notifier
message: |
${{ github.actor }} tagged ${{ github.repository }} ${{ github.event.ref }}
mapcache-rel-1-14-1/.gitignore 0000664 0000000 0000000 00000000065 14653160677 0016125 0 ustar 00root root 0000000 0000000 .*.swp
nbproject/
/build/
/build_vagrant/
/.vagrant/
mapcache-rel-1-14-1/CMakeLists.txt 0000664 0000000 0000000 00000031305 14653160677 0016676 0 ustar 00root root 0000000 0000000 cmake_minimum_required(VERSION 3.0...3.29)
project (MapCache C)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckCSourceCompiles)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_definitions(-DDEBUG)
endif ()
set (MAPCACHE_VERSION_MAJOR 1)
set (MAPCACHE_VERSION_MINOR 14)
set (MAPCACHE_VERSION_REVISION 1)
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR lib)
endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
set(CMAKE_INSTALL_BINDIR bin)
endif(NOT DEFINED CMAKE_INSTALL_BINDIR)
MATH(EXPR MAPCACHE_IS_DEV_VERSION "1-${MAPCACHE_VERSION_MINOR}%2")
if(MAPCACHE_IS_DEV_VERSION)
set (MAPCACHE_VERSION_STRING "${MAPCACHE_VERSION_MAJOR}.${MAPCACHE_VERSION_MINOR}.${MAPCACHE_VERSION_REVISION}")
else(MAPCACHE_IS_DEV_VERSION)
set (MAPCACHE_VERSION_STRING "${MAPCACHE_VERSION_MAJOR}.${MAPCACHE_VERSION_MINOR}dev")
endif(MAPCACHE_IS_DEV_VERSION)
MATH(EXPR MAPCACHE_VERSION_NUM "${MAPCACHE_VERSION_MAJOR}*10000+${MAPCACHE_VERSION_MINOR}*100+${MAPCACHE_VERSION_REVISION}")
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
if (APPLE)
set(CMAKE_FIND_FRAMEWORK "LAST")
endif (APPLE)
macro( report_optional_not_found component )
message(SEND_ERROR "${component} library/component/dependency could not be found.
HINTS:
- disable ${component} support by adding -DWITH_${component}=0
- add the ${component} install directory to the CMAKE_PREFIX_PATH variable (-DCMAKE_PREFIX_PATH=\"/path/to/${component}-install-dir;/path/to/other/dirs\"")
endmacro()
macro( report_mandatory_not_found component )
message(SEND_ERROR "${component} library/component could not be found and is a mandatory dependency
HINT:
- add the ${component} install directory to the CMAKE_PREFIX_PATH variable (-DCMAKE_PREFIX_PATH=\"/path/to/${component}-install-dir;/path/to/other/dirs\"")
endmacro()
macro( report_dependency_error component dependency)
message(SEND_ERROR "${component} support requires ${dependency} support, however ${dependency} support has been disabled.
HINTS:
- re-run with -DWITH_${dependency}=1 (or without -DWITH_${dependency}=0)
- disable ${component} support by adding -DWITH_${component}=0"
)
endmacro()
check_function_exists("strncasecmp" HAVE_STRNCASECMP)
check_function_exists("symlink" HAVE_SYMLINK)
check_function_exists ("timegm" HAVE_TIMEGM)
check_function_exists ("strptime" HAVE_STRPTIME)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_SKIP_BUILD_RPATH FALSE)
if(APPLE)
set(CMAKE_MACOSX_RPATH ON)
endif()
set(CMAKE_LINK_INTERFACE_LIBRARY "")
file(GLOB mapcache_SOURCES lib/*.c )
file(GLOB mapcache_HEADERS include/*.h)
add_library(mapcache SHARED ${mapcache_SOURCES} ${mapcache_HEADERS})
set_target_properties(mapcache PROPERTIES
VERSION ${MAPCACHE_VERSION_STRING}
SOVERSION 1
)
# Add compiler flags for warnings
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror=declaration-after-statement")
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror=declaration-after-statement -Wno-comment")
endif()
#options suported by the cmake builder
option(WITH_PIXMAN "Use pixman for SSE optimized image manipulations" ON)
option(WITH_SQLITE "Use sqlite as a cache/dimension backend" ON)
option(WITH_POSTGRESQL "Use PostgreSQL as a dimension backend" OFF)
option(WITH_BERKELEY_DB "Use Berkeley DB as a cache backend" OFF)
option(WITH_LMDB "Use LMDB as a cache backend" OFF)
option(WITH_MEMCACHE "Use memcache as a cache backend (requires recent apr-util)" OFF)
option(WITH_REDIS "Use redis as a cache backend (requires hiredis library)" OFF)
option(WITH_TIFF "Use TIFFs as a cache backend" OFF)
option(WITH_TIFF_WRITE_SUPPORT "Enable (experimental) support for writable TIFF cache backends" OFF)
option(WITH_GEOTIFF "Allow GeoTIFF metadata creation for TIFF cache backends" OFF)
option(WITH_PCRE "Use PCRE for regex tests" OFF)
option(WITH_PCRE2 "Use PCRE2 for regex tests" OFF)
option(WITH_MAPSERVER "Enable (experimental) support for the mapserver library" OFF)
option(WITH_RIAK "Use Riak as a cache backend" OFF)
option(WITH_GDAL "Choose if GDAL raster support should be built in" ON)
option(WITH_MAPCACHE_DETAIL "Build coverage analysis tool for SQLite caches" ON)
find_package(PNG)
if(PNG_FOUND)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries(mapcache ${PNG_LIBRARIES})
else(PNG_FOUND)
report_mandatory_not_found(PNG)
endif(PNG_FOUND)
find_package(JPEG)
if(JPEG_FOUND)
include_directories(${JPEG_INCLUDE_DIR})
target_link_libraries(mapcache ${JPEG_LIBRARY})
else(JPEG_FOUND)
report_mandatory_not_found(JPEG)
endif(JPEG_FOUND)
find_package(CURL)
if(CURL_FOUND)
include_directories(${CURL_INCLUDE_DIR})
target_link_libraries(mapcache ${CURL_LIBRARY})
else(CURL_FOUND)
report_mandatory_not_found(CURL)
endif(CURL_FOUND)
find_package(APR)
if(APR_FOUND)
include_directories(${APR_INCLUDE_DIR} ${APU_INCLUDE_DIR})
target_link_libraries(mapcache ${APR_LIBRARY} ${APU_LIBRARY})
if(DEFINED APR_CPPFLAGS)
add_definitions("${APR_CPPFLAGS}")
endif(DEFINED APR_CPPFLAGS)
else(APR_FOUND)
report_mandatory_not_found(APR)
endif(APR_FOUND)
if(WITH_MEMCACHE)
include(CheckSymbolExists)
FIND_PATH(tmp_APU_MEMCACHE_DIR
NAMES apr_memcache.h
HINTS ${APU_INCLUDE_DIR}
)
if(tmp_APU_MEMCACHE_DIR)
set(CMAKE_REQUIRED_INCLUDE ${APR_INCLUDE_DIR} ${APU_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${APR_LIBRARY} ${APU_LIBRARY})
check_symbol_exists(apr_memcache_hash "${tmp_APU_MEMCACHE_DIR}/apr_memcache.h" tmp_MEMCACHE_USABLE)
if(tmp_MEMCACHE_USABLE)
set(USE_MEMCACHE 1)
else(tmp_MEMCACHE_USABLE)
MESSAGE(SEND_ERROR "apr_memcache.h found, but seems too old (missing apr_memcache_hash function)")
report_optional_not_found(MEMCACHE)
endif(tmp_MEMCACHE_USABLE)
else(tmp_APU_MEMCACHE_DIR)
MESSAGE(SEND_ERROR "apr_memcache.h not found, your apr-util version may be configured without memcache support")
report_optional_not_found(MEMCACHE)
endif(tmp_APU_MEMCACHE_DIR)
endif(WITH_MEMCACHE)
if(WITH_REDIS)
find_package(Redis)
if(HIREDIS_FOUND)
include_directories(${HIREDIS_INCLUDE_DIR})
target_link_libraries(mapcache ${HIREDIS_LIBRARIES})
set (USE_REDIS 1)
else(HIREDIS_FOUND)
report_optional_not_found(Redis)
endif(HIREDIS_FOUND)
endif(WITH_REDIS)
if(WITH_PIXMAN)
find_package(Pixman)
if(PIXMAN_FOUND)
include_directories(${PIXMAN_INCLUDE_DIR})
target_link_libraries(mapcache ${PIXMAN_LIBRARY})
set (USE_PIXMAN 1)
else(PIXMAN_FOUND)
report_optional_not_found(PIXMAN)
endif(PIXMAN_FOUND)
endif (WITH_PIXMAN)
if(WITH_GDAL)
find_package(GDAL)
if(GDAL_FOUND)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(mapcache ${GDAL_LIBRARY})
set (USE_GDAL 1)
else(GDAL_FOUND)
report_optional_not_found(GDAL)
endif(GDAL_FOUND)
endif(WITH_GDAL)
if(WITH_PCRE)
find_package(PCRE)
if(PCRE_FOUND)
include_directories(${PCRE_INCLUDE_DIR})
target_link_libraries(mapcache ${PCRE_LIBRARY})
set (USE_PCRE 1)
add_definitions(-DPCRE_STATIC)
else(PCRE_FOUND)
report_optional_not_found(PCRE)
endif(PCRE_FOUND)
endif (WITH_PCRE)
if(WITH_PCRE2)
find_package(PCRE2)
if(PCRE2_FOUND)
include_directories(${PCRE2_INCLUDE_DIR})
target_link_libraries(mapcache PCRE2::PCRE2-8)
set (USE_PCRE2 1)
add_definitions(-DPCRE2_CODE_UNIT_WIDTH=8)
else(PCRE2_FOUND)
report_optional_not_found(PCRE2)
endif(PCRE2_FOUND)
endif (WITH_PCRE2)
if(WITH_SQLITE)
find_package(SQLITE)
if(SQLITE_FOUND)
include_directories(${SQLITE_INCLUDE_DIR})
target_link_libraries(mapcache ${SQLITE_LIBRARY})
set (USE_SQLITE 1)
else(SQLITE_FOUND)
report_optional_not_found(SQLITE)
endif(SQLITE_FOUND)
endif (WITH_SQLITE)
if(WITH_POSTGRESQL)
find_package(PostgreSQL)
if(PostgreSQL_FOUND)
include_directories(${PostgreSQL_INCLUDE_DIR})
target_link_libraries(mapcache ${PostgreSQL_LIBRARY})
set (USE_POSTGRESQL 1)
else(POSTGRESQL_FOUND)
report_optional_not_found(POSTGRESQL)
endif(PostgreSQL_FOUND)
endif (WITH_POSTGRESQL)
if(WITH_BERKELEY_DB)
if(NOT BERKELEYDB_FIND_VERSION)
set(BERKELEYDB_FIND_VERSION "4.6")
endif(NOT BERKELEYDB_FIND_VERSION)
find_package(BerkeleyDB)
if(BERKELEYDB_FOUND)
include_directories(${BERKELEYDB_INCLUDE_DIR})
target_link_libraries(mapcache ${BERKELEYDB_LIBRARY})
set (USE_BDB 1)
else(BERKELEYDB_FOUND)
report_optional_not_found(BERKELEY_DB)
endif(BERKELEYDB_FOUND)
endif (WITH_BERKELEY_DB)
if(WITH_LMDB)
if(NOT LMDB_FIND_VERSION)
set(LMDB_FIND_VERSION "0.9.10")
endif(NOT LMDB_FIND_VERSION)
find_package(LMDB)
if(LMDB_FOUND)
include_directories(${LMDB_INCLUDE_DIR})
target_link_libraries(mapcache ${LMDB_LIBRARY})
set(USE_LMDB 1)
else(LMDB_FOUND)
report_optional_not_found(LMDB)
endif(LMDB_FOUND)
endif(WITH_LMDB)
if(WITH_TIFF)
find_package(TIFF)
if(TIFF_FOUND)
include_directories(${TIFF_INCLUDE_DIR})
target_link_libraries(mapcache ${TIFF_LIBRARY})
set (USE_TIFF 1)
else(TIFF_FOUND)
report_optional_not_found(TIFF)
endif(TIFF_FOUND)
endif (WITH_TIFF)
if(WITH_TIFF_WRITE_SUPPORT)
if(USE_TIFF)
set (USE_TIFF_WRITE 1)
else(USE_TIFF)
report_dependency_error(TIFF_WRITE_SUPPORT TIFF)
endif(USE_TIFF)
endif(WITH_TIFF_WRITE_SUPPORT)
if(WITH_GEOTIFF)
find_package(GEOTIFF)
if(GEOTIFF_FOUND)
include_directories(${GEOTIFF_INCLUDE_DIR})
target_link_libraries(mapcache ${GEOTIFF_LIBRARY})
set (USE_GEOTIFF 1)
else(GEOTIFF_FOUND)
report_optional_not_found(GEOTIFF)
endif(GEOTIFF_FOUND)
endif (WITH_GEOTIFF)
if(WITH_MAPSERVER)
find_package(MAPSERVER)
if(MAPSERVER_FOUND)
include_directories(${MAPSERVER_INCLUDE_DIR})
target_link_libraries(mapcache ${MAPSERVER_LIBRARY})
set (USE_MAPSERVER 1)
else(MAPSERVER_FOUND)
report_optional_not_found(MAPSERVER)
endif(MAPSERVER_FOUND)
endif (WITH_MAPSERVER)
if(WITH_RIAK)
find_package(RIAK)
if(RIAK_FOUND)
include_directories(${RIAK_INCLUDE_DIR})
target_link_libraries(mapcache ${RIAK_LIBRARY})
set (USE_RIAK 1)
else(RIAK_FOUND)
report_optional_not_found(RIAK)
endif(RIAK_FOUND)
endif (WITH_RIAK)
if(UNIX)
target_link_libraries(mapcache ${CMAKE_DL_LIBS} m )
endif(UNIX)
configure_file (
"${PROJECT_SOURCE_DIR}/include/mapcache-config.h.in"
"${PROJECT_BINARY_DIR}/include/mapcache-config.h"
)
configure_file (
"${PROJECT_SOURCE_DIR}/include/mapcache-version.h.in"
"${PROJECT_BINARY_DIR}/include/mapcache-version.h"
)
include_directories(include ${PROJECT_BINARY_DIR}/include)
macro(status_optional_component component enabled libpath)
if("${enabled}" EQUAL "1")
message(STATUS " * ${component}: ${libpath}")
else()
message(STATUS " * ${component}: disabled")
endif()
endmacro()
macro(status_optional_feature feature enabled)
if("${enabled}" EQUAL "1" OR "${enabled}" STREQUAL "ON")
message(STATUS " * ${feature}: ENABLED")
else()
message(STATUS " * ${feature}: disabled")
endif()
endmacro()
message(STATUS "* Configured options for the mapcache library")
message(STATUS " * Mandatory components")
message(STATUS " * png: ${PNG_LIBRARY}")
message(STATUS " * jpeg: ${JPEG_LIBRARY}")
message(STATUS " * Curl: ${CURL_LIBRARY}")
message(STATUS " * Apr: ${APR_LIBRARY}")
message(STATUS " * Optional components")
status_optional_component("PIXMAN" "${USE_PIXMAN}" "${PIXMAN_LIBRARY}")
status_optional_component("SQLITE" "${USE_SQLITE}" "${SQLITE_LIBRARY}")
status_optional_component("POSTGRESQL" "${USE_POSTGRESQL}" "${PostgreSQL_LIBRARY}")
status_optional_component("Berkeley DB" "${USE_BDB}" "${BERKELEYDB_LIBRARY}")
status_optional_component("LMDB" "${USE_LMDB}" "${LMDB_LIBRARY}")
status_optional_component("Memcache" "${USE_MEMCACHE}" "${APU_LIBRARY}")
status_optional_component("Redis" "${USE_REDIS}" "${HIREDIS_LIBRARIES} ${HIREDIS_INCLUDE_DIR}")
status_optional_component("TIFF" "${USE_TIFF}" "${TIFF_LIBRARY}")
status_optional_component("GeoTIFF" "${USE_GEOTIFF}" "${GEOTIFF_LIBRARY}")
status_optional_component("Experimental TIFF write support" "${USE_TIFF_WRITE}" "${TIFF_LIBRARY}")
status_optional_component("PCRE" "${USE_PCRE}" "${PCRE_LIBRARY}")
status_optional_component("PCRE2" "${USE_PCRE2}" "${PCRE2-8_LIBRARY}")
status_optional_component("Experimental mapserver support" "${USE_MAPSERVER}" "${MAPSERVER_LIBRARY}")
status_optional_component("RIAK" "${USE_RIAK}" "${RIAK_LIBRARY}")
status_optional_component("GDAL" "${USE_GDAL}" "${GDAL_LIBRARY}")
message(STATUS " * Optional features")
status_optional_feature("MAPCACHE_DETAIL" "${WITH_MAPCACHE_DETAIL}")
INSTALL(TARGETS mapcache DESTINATION ${CMAKE_INSTALL_LIBDIR})
add_subdirectory(util)
add_subdirectory(cgi)
add_subdirectory(apache)
add_subdirectory(nginx)
if (WITH_MAPCACHE_DETAIL)
add_subdirectory(contrib/mapcache_detail)
endif (WITH_MAPCACHE_DETAIL)
mapcache-rel-1-14-1/INSTALL.md 0000664 0000000 0000000 00000000725 14653160677 0015570 0 ustar 00root root 0000000 0000000 Unix compilation instructions
-----------------------------
MapCache now builds with CMake. It seems much happier if it can find apxs, which
means you might need apache2-prefork installed (on ubuntu `apt-get install apache2-prefork-dev`).
```
cd mapcache
mkdir build
cd build
cmake ..
make
sudo make install
```
Detailed instructions and configuration options are maintained in the MapCache
documentation :
https://mapserver.org/mapcache/install.html
mapcache-rel-1-14-1/LICENSE.md 0000664 0000000 0000000 00000002262 14653160677 0015542 0 ustar 00root root 0000000 0000000 MapCache Licensing
==================
Copyright (c) 2008-2024 Open Source Geospatial Foundation.
Copyright (c) 1996-2008 Regents of the University of Minnesota.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies of this Software or works derived from this Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
mapcache-rel-1-14-1/MIGRATION_GUIDE.md 0000664 0000000 0000000 00000004171 14653160677 0016727 0 ustar 00root root 0000000 0000000 Migrating from MapCache 1.12 to 1.14
====================================
* This is a security release, to handle a string formatting injection vulnerability,
and includes other changes.
No backward compatibility issue is expected.
See [MapCache 1.14 Changelog](https://mapserver.org/development/changelog/mapcache/changelog-1-14.html).
Migrating from MapCache 1.10 to 1.12
====================================
* No backward compatibility issue is expected.
See [MapCache 1.12 Changelog](https://mapserver.org/development/changelog/mapcache/changelog-1-12.html)
for a list of bug fixes and new features.
Migrating from MapCache 1.8 to 1.10
===================================
* No backward compatibility issue is expected.
See [MapCache 1.10 Changelog](https://mapserver.org/development/changelog/mapcache/changelog-1-10.html)
for a list of bug fixes and new features.
Migrating from MapCache 1.6 to 1.8
==================================
* ...SQL should be replaced by
...SQL... or
...SQL...
(see [RFC-121](https://mapserver.org/development/rfc/ms-rfc-121.html) for full examples)
Migrating from MapCache 1.4 to 1.6
==================================
* The tileset child has been removed. Time dimensions are now added with
* val1,val2,val3 should be replaced by
val1val2val3
* ... should be replaced by
true....
* ^abc$ should be replaced by
^abc$
* ... should be replaced by
stack....
mapcache-rel-1-14-1/Makefile.vc 0000664 0000000 0000000 00000005463 14653160677 0016213 0 ustar 00root root 0000000 0000000 #
# makefile.vc - Main mapcache makefile for MSVC++
#
#
# To use the makefile:
# - Open a DOS prompt window
# - Run the VCVARS32.BAT script to initialize the VC++ environment variables
# - Start the build with: nmake /f makefile.vc
#
# $Id: $
#
!INCLUDE nmake.opt
BASE_CFLAGS = $(OPTFLAGS)
CFLAGS=$(BASE_CFLAGS) $(MAPCACHE_CFLAGS)
CC= cl
LINK= link
#
# Main mapcache library.
#
MAPCACHE_OBJS = lib\axisorder.obj lib\dimension.obj lib\imageio_mixed.obj lib\service_wms.obj \
lib\buffer.obj lib\ezxml.obj lib\imageio_png.obj lib\service_wmts.obj \
lib\cache_disk.obj lib\lock.obj lib\services.obj lib\cache_bdb.obj \
lib\cache_memcache.obj lib\grid.obj lib\source.obj \
lib\cache_sqlite.obj lib\http.obj lib\source_gdal.obj lib\source_dummy.obj \
lib\cache_tiff.obj lib\image.obj lib\service_demo.obj lib\source_mapserver.obj \
lib\configuration.obj lib\image_error.obj lib\service_kml.obj lib\source_wms.obj \
lib\configuration_xml.obj lib\imageio.obj lib\service_tms.obj lib\tileset.obj \
lib\core.obj lib\imageio_jpeg.obj lib\service_ve.obj lib\util.obj lib\strptime.obj \
$(REGEX_OBJ)
MAPCACHE_FCGI = mapcache.exe
MAPCACHE_APACHE = mod_mapcache.dll
MAPCACHE_SEED = mapcache_seed.exe
#
#
#
default: all
all: $(MAPCACHE_LIB) $(MAPCACHE_FCGI) $(MAPCACHE_APACHE) $(MAPCACHE_SEED)
$(MAPCACHE_LIB): $(MAPCACHE_OBJS)
lib /debug /out:$(MAPCACHE_LIB) $(MAPCACHE_OBJS)
$(MAPCACHE_FCGI): $(MAPCACHE_LIB)
$(CC) $(CFLAGS) cgi\mapcache.c /Fecgi\mapcache.exe $(LIBS)
if exist cgi\$(MAPCACHE_FCGI).manifest mt -manifest cgi\$(MAPCACHE_FCGI).manifest -outputresource:cgi\$(MAPCACHE_FCGI);1
$(MAPCACHE_APACHE): $(MAPCACHE_LIB)
$(CC) $(CFLAGS) apache\mod_mapcache.c /link /DLL /out:apache\mod_mapcache.dll $(LIBS)
if exist apache\$(MAPCACHE_APACHE).manifest mt -manifest apache\$(MAPCACHE_APACHE).manifest -outputresource:apache\$(MAPCACHE_APACHE);2
$(MAPCACHE_SEED): $(MAPCACHE_LIB)
$(CC) $(CFLAGS) util\mapcache_seed.c /Feutil\mapcache_seed.exe $(LIBS)
if exist util\$(MAPCACHE_SEED).manifest mt -manifest util\$(MAPCACHE_SEED).manifest -outputresource:util\$(MAPCACHE_SEED);1
.c.obj:
$(CC) $(CFLAGS) /c $*.c /Fo$*.obj
.cpp.obj:
$(CC) $(CFLAGS) /c $*.cpp /Fo$*.obj
clean:
del lib\*.obj
del *.obj
del *.exp
del apache\$(MAPCACHE_APACHE)
del apache\*.manifest
del apache\*.exp
del apache\*.lib
del apache\*.pdb
del apache\*.ilk
del cgi\$(MAPCACHE_FCGI)
del cgi\*.manifest
del cgi\*.exp
del cgi\*.lib
del cgi\*.pdb
del cgi\*.ilk
del util\$(MAPCACHE_SEED)
del util\*.manifest
del util\*.exp
del util\*.lib
del util\*.pdb
del util\*.ilk
del *.lib
del *.manifest
install: $(MAPCACHE_EXE)
-mkdir $(BINDIR)
copy *.exe $(BINDIR)
mapcache-rel-1-14-1/README.md 0000664 0000000 0000000 00000002025 14653160677 0015412 0 ustar 00root root 0000000 0000000 MapCache
========
[](https://github.com/MapServer/mapcache/actions?query=workflow%3A%22Build%20MapCache%20on%20Linux%22%20branch%3Amain)
[](https://github.com/MapServer/mapcache/actions?query=workflow%3A%22Build%20MapCache%20on%20Windows%22%20branch%3Amain)
Summary
-------
MapCache is a server that implements tile caching to speed up access to WMS layers.
The primary objectives are to be fast and easily deployable, while offering the
essential features (and more!) expected from a tile caching solution.
For more information and complete documentation please
visit:
https://mapserver.org/mapcache/
Questions relating to MapCache use and development can be asked on the
MapServer mailing lists:
https://mapserver.org/community/lists.html
License
-------
See [LICENSE.md](LICENSE.md) mapcache-rel-1-14-1/Vagrantfile 0000664 0000000 0000000 00000001347 14653160677 0016326 0 ustar 00root root 0000000 0000000 # -*- mode: ruby -*-
# vi: set ft=ruby :
require 'socket'
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/focal64"
config.vm.hostname = "mapcache-vagrant"
config.vm.network :forwarded_port, guest: 80, host: 8080
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", 1024, "--cpus", 2]
v.customize ["modifyvm", :id, "--ioapic", "on", "--largepages", "off", "--vtxvpid", "off"]
v.name = "mapcache-vagrant"
end
config.vm.provision "shell", path: "scripts/vagrant/packages.sh"
config.vm.provision "shell", path: "scripts/vagrant/mapcache.sh"
end
mapcache-rel-1-14-1/apache/ 0000775 0000000 0000000 00000000000 14653160677 0015355 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/apache/CMakeLists.txt 0000664 0000000 0000000 00000003130 14653160677 0020112 0 ustar 00root root 0000000 0000000 option(WITH_VERSION_STRING "Show MapCache in server version string" ON)
option(WITH_APACHE "Build Apache Module" ON)
if(WITH_APACHE)
add_library(mod_mapcache MODULE mod_mapcache.c)
set_target_properties(mod_mapcache PROPERTIES PREFIX "")
target_link_libraries(mod_mapcache mapcache)
find_package(APACHE)
if(APACHE_FOUND)
include_directories(${APACHE_INCLUDE_DIR})
target_link_libraries(mod_mapcache ${APACHE_LIBRARY})
else(APACHE_FOUND)
report_mandatory_not_found(APACHE)
endif(APACHE_FOUND)
if(WITH_VERSION_STRING)
set(USE_VERSION_STRING 1)
endif(WITH_VERSION_STRING)
configure_file (
"${PROJECT_SOURCE_DIR}/apache/mod_mapcache-config.h.in"
"${PROJECT_BINARY_DIR}/apache/mod_mapcache-config.h"
)
include_directories("${PROJECT_BINARY_DIR}/apache/")
IF(APPLE)
set_target_properties(mod_mapcache PROPERTIES
LINK_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
ENDIF(APPLE)
message(STATUS "* Apache Module support status:")
status_optional_component("Mapcache Version String" "${USE_VERSION_STRING}" "mod_mapcache/${MAPCACHE_VERSION_STRING}")
if(APACHE_MODULE_DIR)
message(STATUS " * Module will be installed to : ${APACHE_MODULE_DIR}")
else(APACHE_MODULE_DIR)
message(WARNING " * Module will not be automatically installed: module directory not found")
endif(APACHE_MODULE_DIR)
if(APACHE_MODULE_DIR)
INSTALL(TARGETS mod_mapcache DESTINATION ${APACHE_MODULE_DIR})
endif(APACHE_MODULE_DIR)
else(WITH_APACHE)
message(STATUS " * Apache Module support status: DISABLED")
endif(WITH_APACHE)
mapcache-rel-1-14-1/apache/mod_mapcache-config.h.in 0000664 0000000 0000000 00000000151 14653160677 0021773 0 ustar 00root root 0000000 0000000 #ifndef _MOD_MAPCACHE_CONFIG_H
#define _MOD_MAPCACHE_CONFIG_H
#cmakedefine USE_VERSION_STRING 1
#endif
mapcache-rel-1-14-1/apache/mod_mapcache.c 0000664 0000000 0000000 00000061515 14653160677 0020131 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Purpose: MapCache tile caching apache module implementation
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
/*
* Include the core server components.
*/
#include "mod_mapcache-config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "mapcache.h"
#ifndef _WIN32
#include
#endif
#ifdef AP_NEED_SET_MUTEX_PERMS
#include "unixd.h"
#endif
module AP_MODULE_DECLARE_DATA mapcache_module;
typedef struct mapcache_context_apache mapcache_context_apache;
typedef struct mapcache_context_apache_request mapcache_context_apache_request;
typedef struct mapcache_context_apache_server mapcache_context_apache_server;
struct mapcache_context_apache {
mapcache_context ctx;
};
struct mapcache_context_apache_server {
mapcache_context_apache ctx;
server_rec *server;
};
struct mapcache_context_apache_request {
mapcache_context_apache ctx;
request_rec *request;
};
typedef struct mapcache_alias_entry mapcache_alias_entry;
struct mapcache_alias_entry {
char *endpoint;
char *configfile;
mapcache_cfg *cfg;
mapcache_connection_pool *cp;
};
struct mapcache_server_cfg {
apr_array_header_t *aliases; /**< list of mapcache configurations aliased to a server uri */
apr_array_header_t *quickaliases; /**< list of mapcache configurations aliased to a server uri */
};
static int mapcache_alias_matches(const char *uri, const char *alias_fakename);
void apache_context_server_log(mapcache_context *c, mapcache_log_level level, char *message, ...)
{
mapcache_context_apache_server *ctx = (mapcache_context_apache_server*)c;
va_list args;
char *msg;
int ap_log_level;
va_start(args,message);
msg = apr_pvsprintf(c->pool,message,args);
va_end(args);
switch(level) {
case MAPCACHE_DEBUG:
ap_log_level = APLOG_DEBUG;
break;
case MAPCACHE_INFO:
ap_log_level = APLOG_INFO;
break;
case MAPCACHE_NOTICE:
ap_log_level = APLOG_NOTICE;
break;
case MAPCACHE_WARN:
ap_log_level = APLOG_WARNING;
break;
case MAPCACHE_ERROR:
ap_log_level = APLOG_ERR;
break;
case MAPCACHE_CRIT:
ap_log_level = APLOG_CRIT;
break;
case MAPCACHE_ALERT:
ap_log_level = APLOG_ALERT;
break;
case MAPCACHE_EMERG:
ap_log_level = APLOG_EMERG;
break;
default:
ap_log_level = APLOG_WARNING;
}
ap_log_error(APLOG_MARK, ap_log_level, 0, ctx->server,"%s",msg);
}
void apache_context_request_log(mapcache_context *c, mapcache_log_level level, char *message, ...)
{
mapcache_context_apache_request *ctx = (mapcache_context_apache_request*)c;
va_list args;
char *res;
int ap_log_level;
va_start(args,message);
res = apr_pvsprintf(c->pool, message, args);
va_end(args);
switch(level) {
case MAPCACHE_DEBUG:
ap_log_level = APLOG_DEBUG;
break;
case MAPCACHE_INFO:
ap_log_level = APLOG_INFO;
break;
case MAPCACHE_NOTICE:
ap_log_level = APLOG_NOTICE;
break;
case MAPCACHE_WARN:
ap_log_level = APLOG_WARNING;
break;
case MAPCACHE_ERROR:
ap_log_level = APLOG_ERR;
break;
case MAPCACHE_CRIT:
ap_log_level = APLOG_CRIT;
break;
case MAPCACHE_ALERT:
ap_log_level = APLOG_ALERT;
break;
case MAPCACHE_EMERG:
ap_log_level = APLOG_EMERG;
break;
default:
ap_log_level = APLOG_WARNING;
}
ap_log_rerror(APLOG_MARK, ap_log_level, 0, ctx->request, "%s", res);
}
mapcache_context *mapcache_context_request_clone(mapcache_context *ctx)
{
mapcache_context_apache_request *newctx = (mapcache_context_apache_request*)apr_pcalloc(ctx->pool,
sizeof(mapcache_context_apache_request));
mapcache_context *nctx = (mapcache_context*)newctx;
mapcache_context_copy(ctx,nctx);
//apr_pool_create(&nctx->pool,ctx->pool);
apr_pool_create(&nctx->pool,NULL);
apr_pool_cleanup_register(ctx->pool, nctx->pool,(void*)apr_pool_destroy, apr_pool_cleanup_null);
newctx->request = ((mapcache_context_apache_request*)ctx)->request;
return nctx;
}
mapcache_context_apache_request* create_apache_request_context(request_rec *r)
{
mapcache_context_apache_request *rctx = apr_pcalloc(r->pool, sizeof(mapcache_context_apache_request));
mapcache_context *ctx = (mapcache_context*)rctx;
mapcache_context_init(ctx);
ctx->pool = r->pool;
rctx->request = r;
ctx->log = apache_context_request_log;
ctx->clone = mapcache_context_request_clone;
return rctx;
}
static mapcache_context_apache_server* create_apache_server_context(server_rec *s, apr_pool_t *pool)
{
mapcache_context_apache_server *actx = apr_pcalloc(pool, sizeof(mapcache_context_apache_server));
mapcache_context *ctx = (mapcache_context*)actx;
mapcache_context_init(ctx);
ctx->pool = pool;
ctx->config = NULL;
ctx->log = apache_context_server_log;
actx->server = s;
return actx;
}
/* read post body. code taken from "The apache modules book, Nick Kew" */
static void read_post_body(mapcache_context_apache_request *ctx, mapcache_request_proxy *p) {
request_rec *r = ctx->request;
mapcache_context *mctx = (mapcache_context*)ctx;
int bytes,eos;
apr_bucket_brigade *bb, *bbin;
apr_bucket *b;
apr_status_t rv;
const char *clen = apr_table_get(r->headers_in, "Content-Length");
if(clen) {
bytes = strtol(clen, NULL, 0);
if(bytes >= p->rule->max_post_len) {
mctx->set_error(mctx, HTTP_REQUEST_ENTITY_TOO_LARGE, "post request too big");
return;
}
} else {
bytes = p->rule->max_post_len;
}
bb = apr_brigade_create(mctx->pool, r->connection->bucket_alloc);
bbin = apr_brigade_create(mctx->pool, r->connection->bucket_alloc);
p->post_len = 0;
do {
apr_bucket *nextb;
rv = ap_get_brigade(r->input_filters, bbin, AP_MODE_READBYTES, APR_BLOCK_READ, bytes);
if(rv != APR_SUCCESS) {
mctx->set_error(mctx, 500, "failed to read form input");
return;
}
for(b = APR_BRIGADE_FIRST(bbin); b != APR_BRIGADE_SENTINEL(bbin); b = nextb) {
nextb = APR_BUCKET_NEXT(b);
if(APR_BUCKET_IS_EOS(b)) {
eos = 1;
}
if(!APR_BUCKET_IS_METADATA(b)) {
if(b->length != (apr_size_t)(-1)) {
p->post_len += b->length;
if(p->post_len > p->rule->max_post_len) {
apr_bucket_delete(b);
}
}
}
if(p->post_len <= p->rule->max_post_len) {
APR_BUCKET_REMOVE(b);
APR_BRIGADE_INSERT_TAIL(bb, b);
}
}
} while (!eos);
if(p->post_len > p->rule->max_post_len) {
mctx->set_error(mctx, HTTP_REQUEST_ENTITY_TOO_LARGE, "request too big");
return;
}
p->post_buf = apr_palloc(mctx->pool, p->post_len+1);
if(p->post_len> 0) {
rv = apr_brigade_flatten(bb, p->post_buf, &(p->post_len));
if(rv != APR_SUCCESS) {
mctx->set_error(mctx, 500, "error (flatten) reading form data");
return;
}
}
p->post_buf[p->post_len] = 0;
}
static int write_http_response(mapcache_context_apache_request *ctx, mapcache_http_response *response)
{
request_rec *r = ctx->request;
int rc;
char *timestr;
if(response->mtime) {
ap_update_mtime(r, response->mtime);
if((rc = ap_meets_conditions(r)) != OK) {
return rc;
}
timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
apr_rfc822_date(timestr, response->mtime);
apr_table_setn(r->headers_out, "Last-Modified", timestr);
}
if(response->headers && !apr_is_empty_table(response->headers)) {
const apr_array_header_t *elts = apr_table_elts(response->headers);
int i;
for(i=0; inelts; i++) {
apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
if(!strcasecmp(entry.key,"Content-Type")) {
ap_set_content_type(r,entry.val);
} else {
apr_table_set(r->headers_out, entry.key, entry.val);
}
}
}
if(response->data && response->data->size) {
ap_set_content_length(r,response->data->size);
ap_rwrite((void*)response->data->buf, response->data->size, r);
}
r->status = response->code;
return OK;
}
static void mod_mapcache_child_init(apr_pool_t *pool, server_rec *s)
{
mapcache_context *ctx;
ctx = (mapcache_context*)create_apache_server_context(s,pool);
for( ; s ; s=s->next) {
mapcache_server_cfg* cfg = ap_get_module_config(s->module_config, &mapcache_module);
int i,rv;
for(i=0;ialiases->nelts;i++) {
mapcache_alias_entry *alias_entry = APR_ARRAY_IDX(cfg->aliases,i,mapcache_alias_entry*);
mapcache_cache_child_init(ctx,alias_entry->cfg,pool);
if (GC_HAS_ERROR(ctx)) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "%s", ctx->get_error_message(ctx));
}
rv = mapcache_connection_pool_create(alias_entry->cfg, &(alias_entry->cp),pool);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "creating a child process mapcache connection pool on server %s for alias %s", s->server_hostname, alias_entry->endpoint);
if(rv!=APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "failed to create mapcache connection pool");
}
}
for(i=0;iquickaliases->nelts;i++) {
mapcache_alias_entry *alias_entry = APR_ARRAY_IDX(cfg->quickaliases,i,mapcache_alias_entry*);
mapcache_cache_child_init(ctx,alias_entry->cfg,pool);
if (GC_HAS_ERROR(ctx)) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "%s", ctx->get_error_message(ctx));
}
rv = mapcache_connection_pool_create(alias_entry->cfg, &(alias_entry->cp),pool);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "creating a child process mapcache connection pool on server %s for alias %s", s->server_hostname, alias_entry->endpoint);
if(rv!=APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "failed to create mapcache connection pool");
}
}
}
}
static int mapcache_handler(request_rec *r, mapcache_alias_entry *alias_entry) {
apr_table_t *params;
mapcache_request *request = NULL;
mapcache_context_apache_request *apache_ctx = create_apache_request_context(r);
mapcache_context *ctx = (mapcache_context*)apache_ctx;
mapcache_http_response *http_response = NULL;
ctx->config = alias_entry->cfg;
ctx->connection_pool = alias_entry->cp;
ctx->supports_redirects = 1;
ctx->headers_in = r->headers_in;
params = mapcache_http_parse_param_string(ctx, r->args);
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "mapcache dispatch %s",r->path_info);
mapcache_service_dispatch_request(ctx,&request,r->path_info,params,ctx->config);
if(GC_HAS_ERROR(ctx) || !request) {
return write_http_response(apache_ctx,
mapcache_core_respond_to_error(ctx));
}
if(request->type == MAPCACHE_REQUEST_GET_CAPABILITIES) {
mapcache_request_get_capabilities *req_caps = (mapcache_request_get_capabilities*)request;
request_rec *original;
char *url;
if(r->main)
original = r->main;
else
original = r;
url = ap_construct_url(r->pool,original->uri,original);
/*
* remove the path_info from the end of the url (we want the url of the base of the service)
* TODO: is there an apache api to access this ?
*/
if(*(original->path_info) && strcmp(original->path_info,"/")) {
char *end = strstr(url,original->path_info);
if(end) {
/* make sure our url ends with a single '/' */
if(*end == '/') {
char *slash = end;
while((*(--slash))=='/') end--;
end++;
}
*end = '\0';
}
}
http_response = mapcache_core_get_capabilities(ctx,request->service,req_caps,
url,original->path_info,ctx->config);
} else if( request->type == MAPCACHE_REQUEST_GET_TILE) {
mapcache_request_get_tile *req_tile = (mapcache_request_get_tile*)request;
http_response = mapcache_core_get_tile(ctx,req_tile);
} else if( request->type == MAPCACHE_REQUEST_PROXY ) {
const char *buf;
mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
if(r->method_number == M_POST) {
read_post_body(apache_ctx, req_proxy);
if(GC_HAS_ERROR(ctx)) {
return write_http_response(apache_ctx, mapcache_core_respond_to_error(ctx));
}
if(!req_proxy->headers) {
req_proxy->headers = apr_table_make(ctx->pool, 2);
}
apr_table_set(req_proxy->headers, "Content-Type", r->content_type);
if((buf = apr_table_get(r->headers_in,"X-Forwarded-For"))) {
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
apr_table_set(req_proxy->headers, "X-Forwarded-For", apr_psprintf(ctx->pool,"%s, %s", buf, r->connection->remote_ip));
#else
apr_table_set(req_proxy->headers, "X-Forwarded-For", apr_psprintf(ctx->pool,"%s, %s", buf, r->connection->client_ip));
#endif
} else {
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
apr_table_set(req_proxy->headers, "X-Forwarded-For", r->connection->remote_ip);
#else
apr_table_set(req_proxy->headers, "X-Forwarded-For", r->connection->client_ip);
#endif
}
if ((buf = apr_table_get(r->headers_in, "Host"))) {
const char *buf2;
if((buf2 = apr_table_get(r->headers_in,"X-Forwarded-Host"))) {
apr_table_set(req_proxy->headers, "X-Forwarded-Host", apr_psprintf(ctx->pool,"%s, %s",buf2,buf));
} else {
apr_table_set(req_proxy->headers, "X-Forwarded-Host", buf);
}
}
if ((buf = apr_table_get(r->headers_in, "X-Forwarded-Server"))) {
apr_table_set(req_proxy->headers, "X-Forwarded-Server", apr_psprintf(ctx->pool, "%s, %s", buf, r->server->server_hostname));
} else {
apr_table_set(req_proxy->headers, "X-Forwarded-Server", r->server->server_hostname);
}
}
http_response = mapcache_core_proxy_request(ctx, req_proxy);
} else if( request->type == MAPCACHE_REQUEST_GET_MAP) {
mapcache_request_get_map *req_map = (mapcache_request_get_map*)request;
http_response = mapcache_core_get_map(ctx,req_map);
} else if( request->type == MAPCACHE_REQUEST_GET_FEATUREINFO) {
mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)request;
http_response = mapcache_core_get_featureinfo(ctx,req_fi);
} else {
ctx->set_error(ctx,500,"###BUG### unknown request type");
}
if(GC_HAS_ERROR(ctx)) {
return write_http_response(apache_ctx,
mapcache_core_respond_to_error(ctx));
}
return write_http_response(apache_ctx,http_response);
}
static int mod_mapcache_quick_handler(request_rec *r, int lookup) {
mapcache_server_cfg *sconfig = ap_get_module_config(r->server->module_config, &mapcache_module);
mapcache_alias_entry *alias_entry;
int i;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "mapcache quick handler hook on uri %s",r->uri);
if (!sconfig || !sconfig->quickaliases)
return DECLINED;
if (r->uri[0] != '/' && r->uri[0])
return DECLINED;
if(lookup) {
return DECLINED;
}
/* loop through the entries to find one where the alias matches */
for(i=0; iquickaliases->nelts; i++) {
int l;
alias_entry = APR_ARRAY_IDX(sconfig->quickaliases,i,mapcache_alias_entry*);
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "cheking mapcache alias %s against %s",r->uri,alias_entry->endpoint);
if((l=mapcache_alias_matches(r->uri, alias_entry->endpoint))>0) {
if (r->method_number != M_GET && r->method_number != M_POST) {
return HTTP_METHOD_NOT_ALLOWED;
}
r->path_info = &(r->uri[l]);
return mapcache_handler(r,alias_entry);
}
}
return DECLINED;
}
static int mod_mapcache_request_handler(request_rec *r)
{
const char *mapcache_alias;
int i;
mapcache_server_cfg* cfg;
if (!r->handler || strcmp(r->handler, "mapcache")) {
return DECLINED;
}
if (r->method_number != M_GET && r->method_number != M_POST) {
return HTTP_METHOD_NOT_ALLOWED;
}
cfg = ap_get_module_config(r->server->module_config, &mapcache_module);
mapcache_alias = apr_table_get(r->notes,"mapcache_alias_entry");
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "using mapcache config %s", mapcache_config_file);
if(!mapcache_alias) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "mapcache module bug? no mapcache_alias_entry found");
return DECLINED;
}
for(i=0; ialiases->nelts; i++) {
mapcache_alias_entry *alias_entry = APR_ARRAY_IDX(cfg->aliases,i,mapcache_alias_entry*);
if(strcmp(alias_entry->endpoint,mapcache_alias))
continue;
return mapcache_handler(r,alias_entry);
}
return DECLINED; /*should never happen, the fixup phase would not have oriented us here*/
}
static int mod_mapcache_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
mapcache_server_cfg* cfg = ap_get_module_config(s->module_config, &mapcache_module);
if(!cfg) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "configuration not found in server context");
return 1;
}
#ifdef USE_VERSION_STRING
ap_add_version_component(p, MAPCACHE_USERAGENT);
#endif
return 0;
}
static int mapcache_alias_matches(const char *uri, const char *alias_fakename)
{
/* Code for this function from Apache mod_alias module. */
const char *aliasp = alias_fakename, *urip = uri;
while (*aliasp) {
if (*aliasp == '/') {
/* any number of '/' in the alias matches any number in
* the supplied URI, but there must be at least one...
*/
if (*urip != '/')
return 0;
do {
++aliasp;
} while (*aliasp == '/');
do {
++urip;
} while (*urip == '/');
} else {
/* Other characters are compared literally */
if (*urip++ != *aliasp++)
return 0;
}
}
/* Check last alias path component matched all the way */
if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
return 0;
/* Return number of characters from URI which matched (may be
* greater than length of alias, since we may have matched
* doubled slashes)
*/
return urip - uri;
}
static int mapcache_hook_fixups(request_rec *r)
{
int i;
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "running mapcache fixup on %s (handler:%s,filename:%s)",r->uri,r->handler,r->filename);
if(!r->handler) {
mapcache_server_cfg *sconfig = ap_get_module_config(r->server->module_config, &mapcache_module);
mapcache_alias_entry *alias_entry;
if (!sconfig || !sconfig->aliases)
return DECLINED;
if (r->uri[0] != '/' && r->uri[0])
return DECLINED;
/* loop through the entries to find one where the alias matches */
for(i=0; ialiases->nelts; i++) {
int l;
alias_entry = APR_ARRAY_IDX(sconfig->aliases,i,mapcache_alias_entry*);
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "cheking mapcache alias %s against %s",r->uri,alias_entry->endpoint);
if((l=mapcache_alias_matches(r->uri, alias_entry->endpoint))>0) {
r->handler = apr_pstrdup(r->pool,"mapcache");
apr_table_set(r->notes,"mapcache_alias_entry",alias_entry->endpoint);
r->path_info = &(r->uri[l]);
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "setting config %s for alias %s",alias_entry->configfile,alias_entry->endpoint);
//ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "using pathinfo %s from uri %s",r->path_info,r->uri);
return OK;
}
}
}
return DECLINED;
}
static void mod_mapcache_register_hooks(apr_pool_t *p)
{
ap_hook_child_init(mod_mapcache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_config(mod_mapcache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(mod_mapcache_request_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_quick_handler(mod_mapcache_quick_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_fixups(mapcache_hook_fixups, NULL, NULL, APR_HOOK_MIDDLE);
}
static void* mod_mapcache_create_server_conf(apr_pool_t *pool, server_rec *s)
{
mapcache_server_cfg *cfg = apr_pcalloc(pool, sizeof(mapcache_server_cfg));
cfg->aliases = apr_array_make(pool,1,sizeof(mapcache_alias_entry*));
cfg->quickaliases = apr_array_make(pool,1,sizeof(mapcache_alias_entry*));
return cfg;
}
static void *mod_mapcache_merge_server_conf(apr_pool_t *p, void *base_, void *vhost_)
{
mapcache_server_cfg *base = (mapcache_server_cfg*)base_;
mapcache_server_cfg *vhost = (mapcache_server_cfg*)vhost_;
mapcache_server_cfg *cfg = apr_pcalloc(p,sizeof(mapcache_server_cfg));
cfg->aliases = apr_array_append(p, vhost->aliases,base->aliases);
cfg->quickaliases = apr_array_append(p, vhost->quickaliases,base->quickaliases);
#if 0
{
mapcache_alias_entry *e;
int i;
fprintf(stderr,"#### merge called ####\n");
for(i=0;ialiases->nelts;i++) {
e = APR_ARRAY_IDX(base->aliases,i,mapcache_alias_entry*);
fprintf(stderr,"merge base: have alias %s on %s\n",e->configfile,e->endpoint);
}
for(i=0;ialiases->nelts;i++) {
e = APR_ARRAY_IDX(vhost->aliases,i,mapcache_alias_entry*);
fprintf(stderr,"merge vhosts: have alias %s on %s\n",e->configfile,e->endpoint);
}
for(i=0;ialiases->nelts;i++) {
e = APR_ARRAY_IDX(cfg->aliases,i,mapcache_alias_entry*);
fprintf(stderr,"merge result: have alias %s on %s\n",e->configfile,e->endpoint);
}
}
#endif
return cfg;
}
static const char* mapcache_add_alias(cmd_parms *cmd, void *cfg, const char *alias, const char* configfile, const char *quick)
{
mapcache_server_cfg *sconfig;
mapcache_alias_entry *alias_entry;
mapcache_context *ctx;
unsigned forbidden = NOT_IN_DIRECTORY|NOT_IN_FILES;
const char *err;
#if (AP_SERVER_MAJORVERSION_NUMBER > 2) || (AP_SERVER_MINORVERSION_NUMBER >= 4)
forbidden |= NOT_IN_HTACCESS;
#endif
err = ap_check_cmd_context(cmd, forbidden);
if (err) {
return err;
}
sconfig = ap_get_module_config(cmd->server->module_config, &mapcache_module);
if(!sconfig || !sconfig->aliases)
return "no mapcache module config, server bug?";
alias_entry = apr_pcalloc(cmd->pool,sizeof(mapcache_alias_entry));
ctx = (mapcache_context*)create_apache_server_context(cmd->server,cmd->pool);
alias_entry->cfg = mapcache_configuration_create(cmd->pool);
alias_entry->configfile = apr_pstrdup(cmd->pool,configfile);
alias_entry->endpoint = apr_pstrdup(cmd->pool,alias);
mapcache_configuration_parse(ctx,alias_entry->configfile,alias_entry->cfg,0);
if(GC_HAS_ERROR(ctx)) {
return ctx->get_error_message(ctx);
}
mapcache_configuration_post_config(ctx, alias_entry->cfg);
if(GC_HAS_ERROR(ctx)) {
return ctx->get_error_message(ctx);
}
if(mapcache_config_services_enabled(ctx, alias_entry->cfg) <= 0) {
return "no mapcache s configured/enabled, no point in continuing.";
}
if(quick && !strcmp(quick,"quick")) {
APR_ARRAY_PUSH(sconfig->quickaliases,mapcache_alias_entry*) = alias_entry;
ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, "loaded mapcache configuration file from %s on (quick) endpoint %s", alias_entry->configfile, alias_entry->endpoint);
} else {
APR_ARRAY_PUSH(sconfig->aliases,mapcache_alias_entry*) = alias_entry;
ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, "loaded mapcache configuration file from %s on endpoint %s", alias_entry->configfile, alias_entry->endpoint);
}
return NULL;
}
static const command_rec mod_mapcache_cmds[] = {
AP_INIT_TAKE23("MapCacheAlias", mapcache_add_alias ,NULL,RSRC_CONF,"Aliased location of configuration file"),
{ NULL }
} ;
#ifdef APLOG_USE_MODULE
APLOG_USE_MODULE(mapcache);
#endif
module AP_MODULE_DECLARE_DATA mapcache_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
mod_mapcache_create_server_conf,
mod_mapcache_merge_server_conf,
mod_mapcache_cmds,
mod_mapcache_register_hooks
};
/* vim: ts=2 sts=2 et sw=2
*/
mapcache-rel-1-14-1/astyle.sh 0000775 0000000 0000000 00000000257 14653160677 0016000 0 ustar 00root root 0000000 0000000 #!/bin/bash
ASTYLEOPTS="--style=kr --indent=spaces=2 -c --lineend=linux -S"
ASTYLEBIN=astyle
$ASTYLEBIN $ASTYLEOPTS -R '*.c' '*.h'
#find . -name '*.orig' -exec rm -f {} \;
mapcache-rel-1-14-1/benchmark.py 0000664 0000000 0000000 00000004217 14653160677 0016444 0 ustar 00root root 0000000 0000000 #! /usr/bin/env python
import commands
import os
import re
def do_ab_call(url,nthreads,reqs):
cmd="ab -k -c %d -n %d '%s'" % (nthreads,reqs,url)
print cmd
summary={}
ret = commands.getoutput(cmd)
sList = ret.split(os.linesep)
for i, line in enumerate(sList):
if re.match("Requests per second", line) is not None:
val = line.split()
summary['reqspersec']=val[3]
if re.match("Document Length", line) is not None:
val = line.split()
summary['size']=val[2]
return summary
base="http://localhost:8081"
params="LAYERS=test,test3&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&BBOX=-2.8125,47.8125,0,50.625&WIDTH=256&HEIGHT=256"
urls={}
nreqs=400
title="tile merging"
filebase=title
urls['tilecache']="%s/%s?%s" % (base,'tilecache',params)
urls['mapcache best compression']="%s/%s?%s" % (base,'mapcache-best',params)
urls['mapcache default compression']="%s/%s?%s" % (base,'mapcache-default',params)
urls['mapcache fast compression']="%s/%s?%s" % (base,'mapcache-fast',params)
urls['mapcache png quantization']="%s/%s?%s" % (base,'mapcache-pngq',params)
#urls['mapproxy']="http://localhost:8080/service?%s" % (params)
plotfile = open("%s.plot"%(filebase),"w")
datafile = open("%s.dat"%(filebase),"w")
plotfile.write("set terminal pdf\nset key autotitle columnhead\nset output \"%s.pdf\"\nset style data lines\n"%(filebase))
plotfile.write("set xlabel \"concurrent requests\"\n")
plotfile.write("set ylabel \"throughput (requests/sec)\"\n")
plotfile.write("set title \"%s\"\n"%(title))
count=0
for title,url in urls.iteritems():
if count == 0:
plotfile.write("plot \"%s.dat\" using 2:xticlabel(1) index 0"%(filebase))
else:
plotfile.write(",\"\" using 2 index %d"%(count))
count += 1
for nthreads in [1,2,3,4]:
reqs = min(nthreads,4) * nreqs
res = do_ab_call(url,nthreads,reqs)
if nthreads == 1:
datafile.write("\n\nthreads \"%s (%s bytes)\"\n"%(title,res['size']))
datafile.write("%d %s\n"%(nthreads,res['reqspersec']))
plotfile.write("\n")
mapcache-rel-1-14-1/cgi/ 0000775 0000000 0000000 00000000000 14653160677 0014676 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/cgi/CMakeLists.txt 0000664 0000000 0000000 00000002207 14653160677 0017437 0 ustar 00root root 0000000 0000000 option(WITH_CGI "Choose if CGI executable should be built" ON)
option(WITH_FCGI "Choose if CGI executable should support FastCGI" ON)
if(WITH_CGI)
if(NOT DEFINED CMAKE_INSTALL_CGIBINDIR)
set(CMAKE_INSTALL_CGIBINDIR ${CMAKE_INSTALL_BINDIR})
endif(NOT DEFINED CMAKE_INSTALL_CGIBINDIR)
add_executable(mapcache.fcgi mapcache.c)
target_link_libraries(mapcache.fcgi mapcache)
if(WITH_FCGI)
find_package(FCGI)
if(FCGI_FOUND)
include_directories(${FCGI_INCLUDE_DIR})
target_link_libraries(mapcache.fcgi ${FCGI_LIBRARY})
set (USE_FASTCGI 1)
else(FCGI_FOUND)
report_optional_not_found(FCGI)
endif(FCGI_FOUND)
endif (WITH_FCGI)
configure_file (
"${PROJECT_SOURCE_DIR}/cgi/mapcache-cgi-config.h.in"
"${PROJECT_BINARY_DIR}/cgi/mapcache-cgi-config.h"
)
include_directories("${PROJECT_BINARY_DIR}/cgi/")
message(STATUS "* CGI Configuration Options:")
status_optional_component("FastCGI" "${USE_FASTCGI}" "${FCGI_LIBRARY}")
INSTALL(TARGETS mapcache.fcgi RUNTIME DESTINATION ${CMAKE_INSTALL_CGIBINDIR})
else(WITH_CGI)
message(STATUS "* CGI Configuration Options: DISABLED")
endif(WITH_CGI)
mapcache-rel-1-14-1/cgi/mapcache-cgi-config.h.in 0000664 0000000 0000000 00000000142 14653160677 0021215 0 ustar 00root root 0000000 0000000 #ifndef _MAPCACHE_CGI_CONFIG_H
#define _MAPCACHE_CGI_CONFIG_H
#cmakedefine USE_FASTCGI 1
#endif
mapcache-rel-1-14-1/cgi/mapcache.c 0000664 0000000 0000000 00000031157 14653160677 0016612 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Purpose: MapCache tile caching CGI and FastCGI main program
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include "mapcache-cgi-config.h"
#include "mapcache.h"
#include
#include
#include
#include
#include
#include
#ifdef USE_FASTCGI
#include
#endif
#ifndef WIN32
extern char** environ;
#endif
typedef struct mapcache_context_fcgi mapcache_context_fcgi;
typedef struct mapcache_context_fcgi_request mapcache_context_fcgi_request;
static char *err400 = "Bad Request";
static char *err404 = "Not Found";
static char *err500 = "Internal Server Error";
static char *err501 = "Not Implemented";
static char *err502 = "Bad Gateway";
static char *errother = "No Description";
apr_pool_t *global_pool = NULL,*config_pool, *tmp_config_pool;
static char* err_msg(int code)
{
switch(code) {
case 400:
return err400;
case 404:
return err404;
case 500:
return err500;
case 501:
return err501;
case 502:
return err502;
default:
return errother;
}
}
struct mapcache_context_fcgi {
mapcache_context ctx;
};
static mapcache_context* fcgi_context_clone(mapcache_context *ctx)
{
mapcache_context_fcgi *newctx = (mapcache_context_fcgi*)apr_pcalloc(ctx->pool,
sizeof(mapcache_context_fcgi));
mapcache_context *nctx = (mapcache_context*)newctx;
mapcache_context_copy(ctx,nctx);
apr_pool_create(&nctx->pool,ctx->pool);
return nctx;
}
static void fcgi_context_log(mapcache_context *c, mapcache_log_level level, char *message, ...)
{
va_list args;
if(!c->config || level >= c->config->loglevel) {
va_start(args,message);
fprintf(stderr,"%s\n",apr_pvsprintf(c->pool,message,args));
va_end(args);
}
}
static void handle_signal(int signal)
{
apr_pool_destroy(global_pool);
exit(signal);
}
static mapcache_context_fcgi* fcgi_context_create()
{
mapcache_context_fcgi *ctx = apr_pcalloc(global_pool, sizeof(mapcache_context_fcgi));
if(!ctx) {
return NULL;
}
ctx->ctx.pool = global_pool;
mapcache_context_init((mapcache_context*)ctx);
ctx->ctx.log = fcgi_context_log;
ctx->ctx.clone = fcgi_context_clone;
ctx->ctx.config = NULL;
return ctx;
}
static void fcgi_write_response(mapcache_context_fcgi *ctx, mapcache_http_response *response)
{
if(response->code != 200) {
printf("Status: %ld %s\r\n",response->code, err_msg(response->code));
}
if(response->headers && !apr_is_empty_table(response->headers)) {
const apr_array_header_t *elts = apr_table_elts(response->headers);
int i;
for(i=0; inelts; i++) {
apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
printf("%s: %s\r\n", entry.key, entry.val);
}
}
if(response->mtime) {
char *datestr;
char *if_modified_since = getenv("HTTP_IF_MODIFIED_SINCE");
datestr = apr_palloc(ctx->ctx.pool, APR_RFC822_DATE_LEN);
apr_rfc822_date(datestr, response->mtime);
printf("Last-Modified: %s\r\n", datestr);
if(if_modified_since) {
apr_time_t ims_time;
apr_int64_t ims,mtime;
mtime = apr_time_sec(response->mtime);
ims_time = apr_date_parse_http(if_modified_since);
ims = apr_time_sec(ims_time);
if(ims >= mtime) {
printf("Status: 304 Not Modified\r\n");
/*
* "The 304 response MUST NOT contain a message-body"
* https://tools.ietf.org/html/rfc2616#section-10.3.5
*/
printf("\r\n");
return;
}
}
}
if(response->data) {
printf("Content-Length: %ld\r\n\r\n", response->data->size);
fwrite((char*)response->data->buf, response->data->size,1,stdout);
}
}
apr_time_t mtime;
char *conffile;
static void load_config(mapcache_context *ctx, char *filename)
{
apr_file_t *f;
apr_finfo_t finfo;
mapcache_cfg *old_cfg;
mapcache_cfg *cfg;
if((apr_file_open(&f, filename, APR_FOPEN_READ, APR_UREAD | APR_GREAD,
global_pool)) == APR_SUCCESS) {
apr_file_info_get(&finfo, APR_FINFO_MTIME, f);
apr_file_close(f);
} else {
if(!ctx->pool) ctx->pool = global_pool;
ctx->set_error(ctx,500,"failed to open config file %s",filename);
return;
}
if(ctx->config) {
//we already have a loaded configuration, check that the config file hasn't changed
if(finfo.mtime > mtime) {
ctx->log(ctx,MAPCACHE_INFO,"config file has changed, reloading");
} else {
return;
}
}
mtime = finfo.mtime;
/* either we have no config, or it has changed */
old_cfg = ctx->config;
apr_pool_create(&tmp_config_pool,global_pool);
cfg = mapcache_configuration_create(tmp_config_pool);
ctx->config = cfg;
ctx->pool = tmp_config_pool;
mapcache_configuration_parse(ctx,conffile,cfg,1);
if(GC_HAS_ERROR(ctx)) goto failed_load;
mapcache_configuration_post_config(ctx, cfg);
if(GC_HAS_ERROR(ctx)) goto failed_load;
if(mapcache_config_services_enabled(ctx,cfg) <= 0) {
ctx->set_error(ctx,500,"no mapcache s configured/enabled, no point in continuing.");
goto failed_load;
}
/* no error, destroy the previous pool if we are reloading the config */
if(config_pool) {
apr_pool_destroy(config_pool);
}
config_pool = tmp_config_pool;
mapcache_cache_child_init(ctx,cfg,config_pool);
if (GC_HAS_ERROR(ctx)) goto failed_load;
mapcache_connection_pool_create(cfg, &ctx->connection_pool, config_pool);
return;
failed_load:
/* we failed to load the config file */
if(config_pool) {
/* we already have a running configuration, keep it and only log the error to not
* interrupt the already running service */
ctx->log(ctx,MAPCACHE_ERROR,"failed to reload config file %s: %s", conffile,ctx->get_error_message(ctx));
ctx->clear_errors(ctx);
ctx->config = old_cfg;
ctx->pool = config_pool;
apr_pool_destroy(tmp_config_pool);
}
}
static void set_headers(mapcache_context* ctx, char** env)
{
// add all environ settings including HTTP headers to
// a ctx->headers_in apr_table_t
char * key, * val, * kvp, * pair;
int i;
int num_env_var;
apr_table_t* headers;
num_env_var = 0;
while (env[num_env_var] != NULL)
num_env_var++;
headers = apr_table_make(ctx->pool, num_env_var);
for (i = 0; env[i] != NULL; i++) {
kvp = apr_pstrdup(ctx->pool, env[i]);
// convert HTTP header keys from the form HTTP_MY_HEADER to MY-HEADER
key = apr_strtok(kvp, "=", &pair);
key = mapcache_util_str_replace(ctx->pool, key, "HTTP_", "");
key = mapcache_util_str_replace_all(ctx->pool, key, "_", "-");
val = apr_strtok(NULL, "=", &pair);
if (val != NULL) {
apr_table_addn(headers, key, val);
}
else {
apr_table_addn(headers, key, "");
}
}
ctx->headers_in = headers;
}
int main(int argc, const char **argv)
{
mapcache_context_fcgi* globalctx;
mapcache_context* ctx;
apr_table_t *params;
mapcache_request *request = NULL;
char *pathInfo;
mapcache_http_response *http_response;
(void) signal(SIGTERM,handle_signal);
#ifndef _WIN32
(void) signal(SIGUSR1,handle_signal);
#endif
apr_initialize();
atexit(apr_terminate);
if(apr_pool_create(&global_pool,NULL) != APR_SUCCESS) {
return 1;
}
config_pool = NULL;
globalctx = fcgi_context_create();
ctx = (mapcache_context*)globalctx;
conffile = getenv("MAPCACHE_CONFIG_FILE");
#ifdef DEBUG
if(!conffile) {
int i;
for(i=1; ilog(ctx,MAPCACHE_ERROR,"no config file found in MAPCACHE_CONFIG_FILE environment");
return 1;
}
ctx->log(ctx,MAPCACHE_INFO,"mapcache fcgi conf file: %s",conffile);
#ifdef USE_FASTCGI
while (FCGI_Accept() >= 0) {
#endif
ctx->pool = config_pool;
if(!ctx->config || ctx->config->autoreload) {
load_config(ctx,conffile);
if(GC_HAS_ERROR(ctx)) {
fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
goto cleanup;
}
}
apr_pool_create(&(ctx->pool),config_pool);
request = NULL;
pathInfo = getenv("PATH_INFO");
params = mapcache_http_parse_param_string(ctx, getenv("QUERY_STRING"));
mapcache_service_dispatch_request(ctx,&request,pathInfo,params,ctx->config);
if(GC_HAS_ERROR(ctx) || !request) {
fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
goto cleanup;
}
set_headers(ctx, environ);
http_response = NULL;
if(request->type == MAPCACHE_REQUEST_GET_CAPABILITIES) {
mapcache_request_get_capabilities *req = (mapcache_request_get_capabilities*)request;
char *host = getenv("SERVER_NAME");
char *port = getenv("SERVER_PORT");
char *fullhost;
char *url;
if(getenv("HTTPS")) {
if(!port || !strcmp(port,"443")) {
fullhost = apr_psprintf(ctx->pool,"https://%s",host);
} else {
fullhost = apr_psprintf(ctx->pool,"https://%s:%s",host,port);
}
} else {
if(!port || !strcmp(port,"80")) {
fullhost = apr_psprintf(ctx->pool,"http://%s",host);
} else {
fullhost = apr_psprintf(ctx->pool,"http://%s:%s",host,port);
}
}
url = apr_psprintf(ctx->pool,"%s%s/",
fullhost,
getenv("SCRIPT_NAME")
);
http_response = mapcache_core_get_capabilities(ctx,request->service,req,url,pathInfo,ctx->config);
} else if( request->type == MAPCACHE_REQUEST_GET_TILE) {
mapcache_request_get_tile *req_tile = (mapcache_request_get_tile*)request;
http_response = mapcache_core_get_tile(ctx,req_tile);
} else if( request->type == MAPCACHE_REQUEST_PROXY ) {
mapcache_request_proxy *req_proxy = (mapcache_request_proxy*)request;
http_response = mapcache_core_proxy_request(ctx, req_proxy);
// Content-Length is added again in fcgi_write_response
apr_table_unset(http_response->headers, "Content-Length");
} else if( request->type == MAPCACHE_REQUEST_GET_MAP) {
mapcache_request_get_map *req_map = (mapcache_request_get_map*)request;
http_response = mapcache_core_get_map(ctx,req_map);
} else if( request->type == MAPCACHE_REQUEST_GET_FEATUREINFO) {
mapcache_request_get_feature_info *req_fi = (mapcache_request_get_feature_info*)request;
http_response = mapcache_core_get_featureinfo(ctx,req_fi);
#ifdef DEBUG
} else {
ctx->set_error(ctx,500,"###BUG### unknown request type");
#endif
}
if(GC_HAS_ERROR(ctx)) {
fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
goto cleanup;
}
#ifdef DEBUG
if(!http_response) {
ctx->set_error(ctx,500,"###BUG### NULL response");
fcgi_write_response(globalctx, mapcache_core_respond_to_error(ctx));
goto cleanup;
}
#endif
fcgi_write_response(globalctx,http_response);
cleanup:
#ifdef USE_FASTCGI
apr_pool_destroy(ctx->pool);
ctx->clear_errors(ctx);
}
#endif
apr_pool_destroy(global_pool);
apr_terminate();
return 0;
}
/* vim: ts=2 sts=2 et sw=2
*/
mapcache-rel-1-14-1/cmake/ 0000775 0000000 0000000 00000000000 14653160677 0015214 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/cmake/FindAPACHE.cmake 0000664 0000000 0000000 00000001642 14653160677 0017743 0 ustar 00root root 0000000 0000000 #
# APACHE_FOUND - System has APACHE
# APACHE_INCLUDE_DIR - The APACHE include directory
#
# APACHE_LOCATION
# setting this enables search for apache libraries / headers in this location
#
# Include directories
#
find_path(APACHE_INCLUDE_DIR
NAMES httpd.h
PATH_SUFFIXES httpd apache apache2 apache22 apache24
)
if(NOT DEFINED APACHE_MODULE_DIR)
find_program(APXS_BIN NAMES apxs apxs2
PATH_SUFFIXES httpd apache apache2
)
if(APXS_BIN)
EXECUTE_PROCESS(COMMAND ${APXS_BIN} -q LIBEXECDIR
OUTPUT_VARIABLE APACHE_MODULE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
endif(APXS_BIN)
endif(NOT DEFINED APACHE_MODULE_DIR)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set APACHE_FOUND to TRUE if
# all listed variables are TRUE
find_package_handle_standard_args(APACHE DEFAULT_MSG APACHE_INCLUDE_DIR )
mark_as_advanced(APACHE_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindAPR.cmake 0000664 0000000 0000000 00000004603 14653160677 0017444 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# - Find Apache Portable Runtime
# Find the APR includes and libraries
# This module defines
# APR_INCLUDE_DIR and APRUTIL_INCLUDE_DIR, where to find apr.h, etc.
# APR_LIBRARIES and APRUTIL_LIBRARIES, the libraries needed to use APR.
# APR_FOUND and APRUTIL_FOUND, If false, do not try to use APR.
# also defined, but not for general use are
# APR_LIBRARY and APRUTIL_LIBRARY, where to find the APR library.
# APR first.
FIND_PROGRAM(APR_CONFIG_BIN
NAMES apr-config apr-1-config )
if(APR_CONFIG_BIN)
execute_process(
COMMAND ${APR_CONFIG_BIN} --includedir
OUTPUT_VARIABLE HINT_APR_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${APR_CONFIG_BIN} --cppflags
OUTPUT_VARIABLE APR_CPPFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif(APR_CONFIG_BIN)
FIND_PATH(APR_INCLUDE_DIR
NAMES apr.h
HINTS ${HINT_APR_INCLUDE_DIR}
PATH_SUFFIXES apr-1 apr-1.0 apr
)
FIND_LIBRARY(APR_LIBRARY
NAMES apr-1 apr
PATH_SUFFIXES apr-1 apr-1.0 apr
)
set(APR_INCLUDE_DIRS ${APR_INCLUDE_DIR})
set(APR_LIBRARIES ${APR_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(APR DEFAULT_MSG APR_LIBRARY APR_INCLUDE_DIR)
mark_as_advanced(APR_LIBRARY APR_INCLUDE_DIR)
# Next, APRUTIL.
FIND_PATH(APU_INCLUDE_DIR
NAMES apu.h
PATH_SUFFIXES apr-1 apr-1.0 apr
)
FIND_LIBRARY(APU_LIBRARY
NAMES aprutil-1 aprutil
PATH_SUFFIXES apr-1 apr-1.0 apr
)
set(APU_INCLUDE_DIRS ${APU_INCLUDE_DIR})
set(APU_LIBRARIES ${APU_LIBRARY})
find_package_handle_standard_args(APU DEFAULT_MSG APU_LIBRARY APU_INCLUDE_DIR)
mark_as_advanced(APU_LIBRARY APU_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindBerkeleyDB.cmake 0000664 0000000 0000000 00000007105 14653160677 0020772 0 ustar 00root root 0000000 0000000 set(BERKELEYDB_FOUND TRUE)
# set the search path
if (WIN32)
file(GLOB BERKELEYDB_SEARCH_PATH "C:/Program Files/Oracle/Berkeley DB*")
if (NOT BERKELEYDB_SEARCH_PATH)
file(GLOB BERKELEYDB_SEARCH_PATH "C:/Program Files (x86)/Oracle/Berkeley DB*")
endif (NOT BERKELEYDB_SEARCH_PATH)
else (WIN32)
file(GLOB BERKELEYDB_SEARCH_PATH "/usr/local/BerkeleyDB*")
file(GLOB BERKELEYDB_INC_SEARCH_PATH "/usr/local/BerkeleyDB*/include")
file(GLOB BERKELEYDB_LIB_SEARCH_PATH "/usr/local/BerkeleyDB*/lib")
endif (WIN32)
# search for header
find_path(BERKELEYDB_INCLUDE_DIR
NAMES "db.h"
HINTS ${BERKELEYDB_SEARCH_PATH}
${BERKELEYDB_INC_SEARCH_PATH}
)
# header is found
if (BERKELEYDB_INCLUDE_DIR)
# retrieve version information from the header
file(READ "${BERKELEYDB_INCLUDE_DIR}/db.h" DB_H_FILE)
string(REGEX REPLACE ".*#define[ \t]+DB_VERSION_STRING[ \t]+\"([^\"]+)\".*" "\\1" BERKELEYDB_VERSION "${DB_H_FILE}")
string(REGEX REPLACE ".*#define[ \t]+DB_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" BERKELEYDB_VERSION_MAJOR "${DB_H_FILE}")
string(REGEX REPLACE ".*#define[ \t]+DB_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" BERKELEYDB_VERSION_MINOR "${DB_H_FILE}")
string(REGEX REPLACE ".*#define[ \t]+DB_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" BERKELEYDB_VERSION_PATCH "${DB_H_FILE}")
# search for library
if (WIN32)
file(GLOB BERKELEYDB_LIBRARIES
"${DBROOTDIR}/lib/libdb${BERKELEYDB_VERSION_MAJOR}${BERKELEYDB_VERSION_MINOR}.lib"
"${BERKELEYDB_SEARCH_PATH}/lib/libdb${BERKELEYDB_VERSION_MAJOR}${BERKELEYDB_VERSION_MINOR}.lib")
else (WIN32)
find_library(BERKELEYDB_LIBRARY
NAMES "db-${BERKELEYDB_VERSION_MAJOR}.${BERKELEYDB_VERSION_MINOR}" db
HINTS ${BERKELEYDB_SEARCH_PATH}
${BERKELEYDB_LIB_SEARCH_PATH}
)
endif (WIN32)
endif (BERKELEYDB_INCLUDE_DIR)
# header is not found
if (NOT BERKELEYDB_INCLUDE_DIR OR NOT BERKELEYDB_LIBRARY)
set(BERKELEYDB_FOUND_TMP FALSE)
else (NOT BERKELEYDB_INCLUDE_DIR OR NOT BERKELEYDB_LIBRARY)
set(BERKELEYDB_FOUND_TMP TRUE)
endif (NOT BERKELEYDB_INCLUDE_DIR OR NOT BERKELEYDB_LIBRARY)
# check found version
if (BERKELEYDB_FIND_VERSION AND BERKELEYDB_FOUND_TMP)
set(BERKELEYDB_FOUND_VERSION "${BERKELEYDB_VERSION_MAJOR}.${BERKELEYDB_VERSION_MINOR}.${BERKELEYDB_VERSION_PATCH}")
if (BERKELEYDB_FIND_VERSION_EXACT)
if (NOT ${BERKELEYDB_FOUND_VERSION} VERSION_EQUAL ${BERKELEYDB_FIND_VERSION})
set(BERKELEYDB_FOUND_TMP FALSE)
endif (NOT ${BERKELEYDB_FOUND_VERSION} VERSION_EQUAL ${BERKELEYDB_FIND_VERSION})
else (BERKELEYDB_FIND_VERSION_EXACT)
if (${BERKELEYDB_FOUND_VERSION} VERSION_LESS ${BERKELEYDB_FIND_VERSION})
set(BERKELEYDB_FOUND_TMP FALSE)
endif (${BERKELEYDB_FOUND_VERSION} VERSION_LESS ${BERKELEYDB_FIND_VERSION})
endif (BERKELEYDB_FIND_VERSION_EXACT)
if (NOT BERKELEYDB_FOUND_TMP)
message(SEND_ERROR "Berkeley DB library found, but with wrong version v${BERKELEYDB_FIND_VERSION} (${BERKELEYDB_FOUND_VERSION} was found)")
unset(BERKELEYDB_INCLUDE_DIR)
unset(BERKELEYDB_LIBRARY)
endif (NOT BERKELEYDB_FOUND_TMP)
endif (BERKELEYDB_FIND_VERSION AND BERKELEYDB_FOUND_TMP)
set(BERKELEYDB_INCLUDE_DIRS ${BERKELEYDB_INCLUDE_DIR})
set(BERKELEYDB_LIBRARIES ${BERKELEYDB_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(BerkeleyDB DEFAULT_MSG BERKELEYDB_LIBRARY BERKELEYDB_INCLUDE_DIR)
mark_as_advanced(BERKELEYDB_LIBRARY BERKELEYDB_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindFCGI.cmake 0000664 0000000 0000000 00000000600 14653160677 0017523 0 ustar 00root root 0000000 0000000 # Look for the header file.
find_path(FCGI_INCLUDE_DIR NAMES fastcgi.h)
# Look for the library.
find_library(FCGI_LIBRARY NAMES fcgi)
set(FCGI_INCLUDE_DIRS ${FCGI_INCLUDE_DIR})
set(FCGI_LIBRARIES ${FCGI_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FCGI DEFAULT_MSG FCGI_LIBRARY FCGI_INCLUDE_DIR)
mark_as_advanced(FCGI_LIBRARY FCGI_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindGDAL.cmake 0000664 0000000 0000000 00000006270 14653160677 0017533 0 ustar 00root root 0000000 0000000 # Locate gdal
#
# This module accepts the following environment variables:
#
# GDAL_DIR or GDAL_ROOT - Specify the location of GDAL
#
# This module defines the following CMake variables:
#
# GDAL_FOUND - True if libgdal is found
# GDAL_LIBRARY - A variable pointing to the GDAL library
# GDAL_INCLUDE_DIR - Where to find the headers
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
#
# $GDALDIR is an environment variable that would
# correspond to the ./configure --prefix=$GDAL_DIR
# used in building gdal.
#
# Created by Eric Wing. I'm not a gdal user, but OpenSceneGraph uses it
# for osgTerrain so I whipped this module together for completeness.
# I actually don't know the conventions or where files are typically
# placed in distros.
# Any real gdal users are encouraged to correct this (but please don't
# break the OS X framework stuff when doing so which is what usually seems
# to happen).
# This makes the presumption that you are include gdal.h like
#
#include "gdal.h"
find_path(GDAL_INCLUDE_DIR gdal.h
HINTS
ENV GDAL_DIR
ENV GDAL_ROOT
PATH_SUFFIXES
gdal
GDAL
gdal1
PATHS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
if(UNIX)
# Use gdal-config to obtain the library version (this should hopefully
# allow us to -lgdal1.x.y where x.y are correct version)
# For some reason, libgdal development packages do not contain
# libgdal.so...
find_program(GDAL_CONFIG gdal-config
HINTS
ENV GDAL_DIR
ENV GDAL_ROOT
PATH_SUFFIXES bin
PATHS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
if(GDAL_CONFIG)
execute_process(COMMAND ${GDAL_CONFIG} --libs OUTPUT_VARIABLE GDAL_CONFIG_LIBS)
if(GDAL_CONFIG_LIBS)
string(REGEX MATCHALL "-l[^ ]+" _gdal_dashl ${GDAL_CONFIG_LIBS})
string(REGEX REPLACE "-l" "" _gdal_lib "${_gdal_dashl}")
string(REGEX MATCHALL "-L[^ ]+" _gdal_dashL ${GDAL_CONFIG_LIBS})
string(REGEX REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}")
endif()
endif()
endif()
find_library(GDAL_LIBRARY
NAMES ${_gdal_lib} gdal gdal_i gdal1.5.0 gdal1.4.0 gdal1.3.2 GDAL
HINTS
ENV GDAL_DIR
ENV GDAL_ROOT
${_gdal_libpath}
PATH_SUFFIXES lib
PATHS
/sw
/opt/local
/opt/csw
/opt
/usr/freeware
)
set(GDAL_LIBRARIES ${GDAL_LIBRARY})
set(GDAL_INCLUDE_DIRS ${GDAL_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL DEFAULT_MSG GDAL_LIBRARY GDAL_INCLUDE_DIR)
MARK_AS_ADVANCED(GDAL_LIBRARY GDAL_INCLUDE_DIR GDAL_CONFIG)
mapcache-rel-1-14-1/cmake/FindGEOS.cmake 0000664 0000000 0000000 00000001650 14653160677 0017556 0 ustar 00root root 0000000 0000000 # Find the native GEOS(Geometry Engine - Open Source) includes and libraries.
#
# This module defines:
#
# GEOS_INCLUDE_DIR, where to find geos.h, etc.
# GEOS_LIBRARY, libraries to link against to use GEOS, using the geos_c library
# GEOS_FOUND, True if found, false if one of the above are not found.
#---
# Find include path:
# Note: Version < 3.3.0 do not have geos.h in the geos sub directory; hence,
# the check for both "geos/geos.h" and "geos.h".
#---
find_path( GEOS_INCLUDE_DIR
NAMES geos_c.h
PATH_SUFFIXES geos)
# Find GEOS C library:
find_library( GEOS_LIBRARY NAMES geos_c )
set(GEOS_INCLUDE_DIRS ${GEOS_INCLUDE_DIR})
set(GEOS_LIBRARIES ${GEOS_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args( GEOS DEFAULT_MSG
GEOS_LIBRARY
GEOS_INCLUDE_DIR )
MARK_AS_ADVANCED(GEOS_LIBRARY GEOS_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindGEOTIFF.cmake 0000664 0000000 0000000 00000000675 14653160677 0020112 0 ustar 00root root 0000000 0000000 find_path(GEOTIFF_INCLUDE_DIR
NAMES geotiff.h
PATH_SUFFIXES libgeotiff geotiff)
find_library(GEOTIFF_LIBRARY
NAMES geotiff geotiff3
PATH_SUFFIXES geotiff )
set(GEOTIFF_INCLUDE_DIRS ${GEOTIFF_INCLUDE_DIR})
set(GEOTIFF_LIBRARIES ${GEOTIFF_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GEOTIFF DEFAULT_MSG GEOTIFF_LIBRARY GEOTIFF_INCLUDE_DIR)
mark_as_advanced(GEOTIFF_LIBRARY GEOTIFF_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindLMDB.cmake 0000664 0000000 0000000 00000000756 14653160677 0017545 0 ustar 00root root 0000000 0000000 set(LMDB_FOUND TRUE)
set(LMDB_INC_SEARCH_PATH "/usr/include")
set(LMDB_LIB_SEARCH_PATH "/usr/lib")
find_path(LMDB_INCLUDE_DIR NAMES "lmdb.h" HINTS ${LMDB_INC_SEARCH_PATH})
find_library(LMDB_LIBRARY NAMES "lmdb" HINTS ${LMDB_LIB_SEARCH_PATH})
set(LMDB_INCLUDE_DIRS ${LMDB_INCLUDE_DIR})
set(LMDB_LIBRARIES ${LMDB_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LMDB DEFAULT_MSG LMDB_LIBRARY LMDB_INCLUDE_DIR)
mark_as_advanced(LMDB_LIBRARY LMDB_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindMAPSERVER.cmake 0000664 0000000 0000000 00000000661 14653160677 0020366 0 ustar 00root root 0000000 0000000
FIND_PATH(MAPSERVER_INCLUDE_DIR
NAMES mapserver.h
PATH_SUFFIXES mapserver
)
FIND_LIBRARY(MAPSERVER_LIBRARY
NAMES mapserver
)
set(MAPSERVER_INCLUDE_DIRS ${MAPSERVER_INCLUDE_DIR})
set(MAPSERVER_LIBRARIES ${MAPSERVER_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MAPSERVER DEFAULT_MSG MAPSERVER_LIBRARY MAPSERVER_INCLUDE_DIR)
mark_as_advanced(MAPSERVER_LIBRARY MAPSERVER_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindPCRE.cmake 0000664 0000000 0000000 00000000532 14653160677 0017550 0 ustar 00root root 0000000 0000000
FIND_PATH(PCRE_INCLUDE_DIR
NAMES pcre.h
)
FIND_LIBRARY(PCRE_LIBRARY
NAMES pcre pcred
)
set(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR})
set(PCRE_LIBRARIES ${PCRE_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR)
mark_as_advanced(PCRE_LIBRARY PCRE_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindPCRE2.cmake 0000664 0000000 0000000 00000002154 14653160677 0017634 0 ustar 00root root 0000000 0000000 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file COPYING-CMAKE-SCRIPTS or https://cmake.org/licensing for details.
#.rst
# FindPCRE2
# ~~~~~~~~~
# Copyright (C) 2017-2018, Hiroshi Miura
#
# Find the native PCRE2 headers and libraries.
find_path(PCRE2_INCLUDE_DIR NAMES pcre2.h)
find_library(PCRE2-8_LIBRARY NAMES pcre2-8 pcre2-8d pcre2-8-static pcre2-8-staticd NAMES_PER_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PCRE2
REQUIRED_VARS PCRE2-8_LIBRARY PCRE2_INCLUDE_DIR)
mark_as_advanced(PCRE2_INCLUDE_DIR PCRE2-8_LIBRARY)
if(PCRE2_FOUND)
list(APPEND PCRE2_LIBRARIES "${PCRE2-8_LIBRARY}")
set(PCRE2_INCLUDE_DIRS "${PCRE2_INCLUDE_DIR}")
if(NOT TARGET PCRE2::PCRE2-8)
add_library(PCRE2::PCRE2-8 UNKNOWN IMPORTED)
set_target_properties(PCRE2::PCRE2-8 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PCRE2_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${PCRE2-8_LIBRARY}")
endif()
endif()
mapcache-rel-1-14-1/cmake/FindPixman.cmake 0000664 0000000 0000000 00000001272 14653160677 0020255 0 ustar 00root root 0000000 0000000 FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_PIXMAN pixman)
if(NOT PC_PIXMAN_FOUND)
PKG_CHECK_MODULES(PC_PIXMAN pixman-1)
endif(NOT PC_PIXMAN_FOUND)
FIND_PATH(PIXMAN_INCLUDE_DIR
NAMES pixman.h
HINTS ${PC_PIXMAN_INCLUDEDIR}
${PC_PIXMAN_INCLUDE_DIR}
PATH_SUFFIXES pixman pixman-1
)
FIND_LIBRARY(PIXMAN_LIBRARY
NAMES pixman pixman-1
HINTS ${PC_PIXMAN_LIBDIR}
${PC_PIXMAN_LIBRARY_DIRS}
)
set(PIXMAN_INCLUDE_DIRS ${PIXMAN_INCLUDE_DIR})
set(PIXMAN_LIBRARIES ${PIXMAN_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Pixman DEFAULT_MSG PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
mark_as_advanced(PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindRIAK.cmake 0000664 0000000 0000000 00000000526 14653160677 0017550 0 ustar 00root root 0000000 0000000
FIND_PATH(RIAK_INCLUDE_DIR
NAMES riack.h
)
FIND_LIBRARY(RIAK_LIBRARY
NAMES riack
)
set(RIAK_INCLUDE_DIRS ${RIAK_INCLUDE_DIR})
set(RIAK_LIBRARIES ${RIAK_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RIAK DEFAULT_MSG RIAK_LIBRARY RIAK_INCLUDE_DIR)
mark_as_advanced(RIAK_LIBRARY RIAK_INCLUDE_DIR)
mapcache-rel-1-14-1/cmake/FindRedis.cmake 0000664 0000000 0000000 00000001572 14653160677 0020072 0 ustar 00root root 0000000 0000000 IF (HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
SET (HIREDIS_FOUND TRUE)
ELSE(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
FIND_PATH(HIREDIS_INCLUDE_DIR hiredis/hiredis.h
/usr/include/
/usr/include/hiredis
/usr/local/include/
/usr/local/include/hiredis
/opt/local/include/
/opt/local/include/hiredis
)
FIND_LIBRARY(HIREDIS_LIBRARIES NAMES hiredis libhiredis
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
IF(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
SET(HIREDIS_FOUND TRUE)
MESSAGE(STATUS "Found hiredis: ${HIREDIS_INCLUDE_DIR}, ${HIREDIS_LIBRARIES}")
ELSE(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
SET(HIREDIS_FOUND FALSE)
MESSAGE(STATUS "hiredis client library not found.")
ENDIF(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
MARK_AS_ADVANCED(HIREDIS_INCLUDE_DIR HIREDIS_LIBRARIES)
ENDIF(HIREDIS_INCLUDE_DIR AND HIREDIS_LIBRARIES)
mapcache-rel-1-14-1/cmake/FindSQLITE.cmake 0000664 0000000 0000000 00000000633 14653160677 0020022 0 ustar 00root root 0000000 0000000
FIND_PATH(SQLITE_INCLUDE_DIR
NAMES sqlite3.h
PATH_SUFFIXES sqlite sqlite3
)
FIND_LIBRARY(SQLITE_LIBRARY
NAMES sqlite3 sqlite3_i
)
set(SQLITE_INCLUDE_DIRS ${SQLITE_INCLUDE_DIR})
set(SQLITE_LIBRARIES ${SQLITE_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SQLITE DEFAULT_MSG SQLITE_LIBRARY SQLITE_INCLUDE_DIR)
mark_as_advanced(SQLITE_LIBRARY SQLITE_INCLUDE_DIR)
mapcache-rel-1-14-1/contrib/ 0000775 0000000 0000000 00000000000 14653160677 0015574 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/contrib/mapcache_detail/ 0000775 0000000 0000000 00000000000 14653160677 0020657 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/contrib/mapcache_detail/CMakeLists.txt 0000664 0000000 0000000 00000003440 14653160677 0023420 0 ustar 00root root 0000000 0000000 option(WITH_GEOS
"Choose if GEOS geometry operations support should be built in" ON)
option(WITH_OGR
"Choose if OGR/GDAL input vector support should be built in" ON)
add_executable(mapcache_detail mapcache_detail.c)
target_link_libraries(mapcache_detail mapcache)
if (WITH_SQLITE)
find_package(SQLITE)
if(SQLITE_FOUND)
include_directories(${SQLITE_INCLUDE_DIR})
target_link_libraries(mapcache_detail ${SQLITE_LIBRARY})
else(SQLITE_FOUND)
report_mandatory_not_found(SQLITE)
endif(SQLITE_FOUND)
else (WITH_SQLITE)
report_dependency_error(MAPCACHE_DETAIL SQLITE)
endif (WITH_SQLITE)
if (WITH_OGR)
find_package(GDAL)
if (GDAL_FOUND)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(mapcache_detail ${GDAL_LIBRARY})
set (USE_OGR 1)
else (GDAL_FOUND)
report_optional_not_found(GDAL)
endif (GDAL_FOUND)
endif (WITH_OGR)
if (WITH_GEOS)
find_package(GEOS)
if (GEOS_FOUND)
include_directories(${GEOS_INCLUDE_DIR})
target_link_libraries(mapcache_detail ${GEOS_LIBRARY})
set (USE_GEOS 1)
else (GEOS_FOUND)
report_optional_not_found(GEOS)
endif (GEOS_FOUND)
endif (WITH_GEOS)
set (CURRENT_BINARY_DIR "${PROJECT_BINARY_DIR}/contrib/mapcache_detail/")
include_directories("${CURRENT_BINARY_DIR}")
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/mapcache_detail_config.h.in"
"${CURRENT_BINARY_DIR}/mapcache_detail_config.h"
)
message(STATUS "* mapcache_detail Configuration Options:")
message(STATUS " * Mandatory components")
message(STATUS " * SQLite: ${SQLITE_LIBRARY}")
message(STATUS " * Optional components")
status_optional_component("GEOS" "${USE_GEOS}" "${GEOS_LIBRARY}")
status_optional_component("OGR" "${USE_OGR}" "${GDAL_LIBRARY}")
INSTALL(TARGETS mapcache_detail
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
mapcache-rel-1-14-1/contrib/mapcache_detail/mapcache_detail.c 0000664 0000000 0000000 00000174222 14653160677 0024116 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Purpose: MapCache utility program for preparing cache export
* Author: Jerome Boue and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include "mapcache_detail_config.h"
#if defined(USE_OGR) && defined(USE_GEOS)
#define USE_CLIPPERS
#endif
#include
#include
#include
#include
#include
#ifndef _WIN32
#include
#endif
#include
#include
#include
#include
#include
#include "mapcache.h"
#include "ezxml.h"
#include "cJSON.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
#include
#else
#include
#endif
#ifdef USE_CLIPPERS
#include
#include
#include
#include
#endif // USE_CLIPPERS
///////////////////////////////////////////////////////////////////////////////
//
// Command Line Interface
//
///////////////////////////////////////////////////////////////////////////////
// List of command line options
const apr_getopt_option_t optlist[] = {
{ "help", 'h', FALSE, "Display this message and exit" },
{ "config", 'c', TRUE, "Configuration file"
" (/path/to/mapcache.xml)" },
{ "dimension", 'D', TRUE, "Set the value of a dimension: format"
" DIMENSIONNAME=VALUE. Can be used"
" multiple times for multiple"
" dimensions" },
{ "tileset", 't', TRUE, "Tileset to analyze" },
{ "grid", 'g', TRUE, "Grid to analyze" },
{ "extent", 'e', TRUE, "Extent to analyze:"
"format minx,miny,maxx,maxy. Cannot be"
" used with --ogr-datasource." },
#ifdef USE_CLIPPERS
{ "ogr-datasource", 'd', TRUE, "OGR data source to get features from."
" Cannot be used with --extent." },
{ "ogr-layer", 'l', TRUE, "OGR layer inside OGR data source. Cannot"
" be used with --ogr-sql." },
{ "ogr-where", 'w', TRUE, "Filter to apply on OGR layer features."
" Cannot be used with --ogr-sql." },
{ "ogr-sql", 's', TRUE, "SQL query to filter inside OGR data"
" source. Cannot be used with"
" --ogr-layer or --ogr-where." },
#endif // USE_CLIPPERS
{ "zoom", 'z', TRUE, "Set min and max zoom levels to analyze,"
" separated by a comma, eg: 12,15" },
{ "query", 'q', TRUE, "Set query for counting tiles in a"
" rectangle. Default value works with"
" default schema of SQLite caches." },
{ "short-output", 'o', FALSE, "Only existing SQLite files are reported,"
" missing SQLite files are still taken"
" into account for level and global"
" coverage." },
{ "endofopt", 0, FALSE, "End of options" }
};
// Extract basename from a path
const char * base_name(const char * path)
{
const char *subdir, *basename=path;
for (subdir=path ; (subdir=strchr(subdir, '/')) ; basename=++subdir);
return basename;
}
// Get terminal columns
int termcols()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbi)) csbi.dwSize.X = 0;
return csbi.dwSize.X;
#else
struct winsize w;
if (ioctl(STDERR_FILENO, TIOCGWINSZ, &w) < 0) w.ws_col = 0;
return w.ws_col;
#endif
}
// Display help message
void usage(apr_pool_t * pool, const char * path, char * msg, ...)
{
int i;
const char * name = base_name(path);
if (msg) {
va_list args;
va_start(args, msg);
fprintf(stderr, "Error: %s: ", name);
vfprintf(stderr, msg, args);
fprintf(stderr, "\n\n");
va_end(args);
}
fprintf(stderr, "\nUsage: %s \n\n", name);
for (i=0 ; optlist[i].optch ; i++)
{
char ** words;
int linewidth = 16;
const int cols = termcols();
fprintf(stderr, " -%c | --%s%s\n ",
optlist[i].optch, optlist[i].name,
optlist[i].has_arg ? " " : "");
apr_tokenize_to_argv(optlist[i].description, &words, pool);
for (;*words;words++) {
linewidth += strlen(*words)+1;
if (cols > 0 && linewidth > cols) {
fprintf(stderr, "\n ");
linewidth = 16 + strlen(*words)+1;
}
fprintf(stderr, "%s ", *words);
}
fprintf(stderr, "\n");
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Hooks for support libraries
//
///////////////////////////////////////////////////////////////////////////////
#ifdef USE_CLIPPERS
// GEOS notice function
void notice(const char *fmt,...)
{
va_list ap;
fprintf(stdout,"{ notice: ");
va_start(ap,fmt);
vfprintf(stdout,fmt,ap);
va_end(ap);
fprintf(stdout," }\n");
}
// GEOS log_and_exit function
void log_and_exit(const char *fmt,...)
{
va_list ap;
fprintf(stderr,"{ error: ");
va_start(ap,fmt);
vfprintf(stderr,fmt,ap);
va_end(ap);
fprintf(stderr," }\n");
exit(1);
}
#endif // USE_CLIPPERS
// Mapcache log function
void mapcache_log(mapcache_context *ctx, mapcache_log_level lvl, char *msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
fprintf(stderr, "\n");
}
// cJSON memory allocation Hook on APR pool mechanism
static apr_pool_t * _pool_for_cJSON_malloc_hook;
static void * _malloc_for_cJSON(size_t size) {
return apr_palloc(_pool_for_cJSON_malloc_hook,size);
}
static void _free_for_cJSON(void *ptr) { }
static void _create_json_pool(apr_pool_t * parent_pool) {
cJSON_Hooks hooks = { _malloc_for_cJSON, _free_for_cJSON };
apr_pool_create(&_pool_for_cJSON_malloc_hook,parent_pool);
cJSON_InitHooks(&hooks);
}
static void _destroy_json_pool() {
apr_pool_destroy(_pool_for_cJSON_malloc_hook);
}
///////////////////////////////////////////////////////////////////////////////
//
// Conversions between various geometry formats
//
///////////////////////////////////////////////////////////////////////////////
#ifdef USE_CLIPPERS
// Convert `mapcache_extent` to `GEOSGeometry` polygon
GEOSGeometry * mapcache_extent_to_GEOSGeometry(const mapcache_extent *extent)
{
GEOSCoordSequence *cs = GEOSCoordSeq_create(5,2);
GEOSGeometry *lr = GEOSGeom_createLinearRing(cs);
GEOSGeometry *bb = GEOSGeom_createPolygon(lr,NULL,0);
GEOSCoordSeq_setX(cs,0,extent->minx);
GEOSCoordSeq_setY(cs,0,extent->miny);
GEOSCoordSeq_setX(cs,1,extent->maxx);
GEOSCoordSeq_setY(cs,1,extent->miny);
GEOSCoordSeq_setX(cs,2,extent->maxx);
GEOSCoordSeq_setY(cs,2,extent->maxy);
GEOSCoordSeq_setX(cs,3,extent->minx);
GEOSCoordSeq_setY(cs,3,extent->maxy);
GEOSCoordSeq_setX(cs,4,extent->minx);
GEOSCoordSeq_setY(cs,4,extent->miny);
return bb;
}
// Update `GEOSGeometry` polygon created with
// `mapcache_extent_to_GEOSGeometry()` with values from another
// `mapcache_extent`
void update_GEOSGeometry_with_mapcache_extent(GEOSGeometry *bb,
const mapcache_extent *extent)
{
GEOSGeometry *lr = (GEOSGeometry *)GEOSGetExteriorRing(bb);
GEOSCoordSequence *cs = (GEOSCoordSequence *)GEOSGeom_getCoordSeq(lr);
GEOSCoordSeq_setX(cs,0,extent->minx);
GEOSCoordSeq_setY(cs,0,extent->miny);
GEOSCoordSeq_setX(cs,1,extent->maxx);
GEOSCoordSeq_setY(cs,1,extent->miny);
GEOSCoordSeq_setX(cs,2,extent->maxx);
GEOSCoordSeq_setY(cs,2,extent->maxy);
GEOSCoordSeq_setX(cs,3,extent->minx);
GEOSCoordSeq_setY(cs,3,extent->maxy);
GEOSCoordSeq_setX(cs,4,extent->minx);
GEOSCoordSeq_setY(cs,4,extent->miny);
}
// Convert `GEOSGeometry` to GeoJSON string
char * GEOSGeometry_to_GeoJSON(const GEOSGeometry *g)
{
OGRGeometryH geom;
GEOSWKTWriter * wr = GEOSWKTWriter_create();
char * wkt = GEOSWKTWriter_write(wr,g);
char * geojson = NULL;
OGR_G_CreateFromWkt(&wkt,NULL,&geom);
geojson = OGR_G_ExportToJson(geom);
OGR_G_DestroyGeometry(geom);
GEOSWKTWriter_destroy(wr);
return geojson;
}
// Convert `GEOSGeometry` to `cJSON` structure embedding GeoJSON data
cJSON * GEOSGeometry_to_cJSON(const GEOSGeometry *g)
{
char * geojson = GEOSGeometry_to_GeoJSON(g);
cJSON * jgeom = cJSON_Parse(geojson);
CPLFree(geojson);
return jgeom;
}
// Convert `mapcache_extent` to GeoJSON string
char * mapcache_extent_to_GeoJSON(const mapcache_extent *extent)
{
return GEOSGeometry_to_GeoJSON(mapcache_extent_to_GEOSGeometry(extent));
}
// Convert `mapcache_extent` to `cJSON` structure embedding GeoJSON data
cJSON * mapcache_extent_to_cJSON(const mapcache_extent *extent)
{
return GEOSGeometry_to_cJSON(mapcache_extent_to_GEOSGeometry(extent));
}
// Convert `OGRLayerH` to `cJSON` structure embedding GeoJSON data
cJSON * OGRLayerH_to_cJSON(const OGRLayerH layer)
{
cJSON *jlayer, *jfeatures, *jfeature, *jgeom;
OGRFeatureH feature;
int nfeat = 0;
jlayer = cJSON_CreateObject();
cJSON_AddStringToObject(jlayer, "type", "FeatureCollection");
jfeatures = cJSON_AddArrayToObject(jlayer, "features");
OGR_L_ResetReading(layer);
while ((feature = OGR_L_GetNextFeature(layer))) {
OGRGeometryH ogr_geom = OGR_F_GetGeometryRef(feature);
char * geojson = OGR_G_ExportToJson(ogr_geom);
jgeom = cJSON_Parse(geojson);
CPLFree(geojson);
jfeature = cJSON_CreateObject();
cJSON_AddItemToObject(jfeatures, "", jfeature);
cJSON_AddStringToObject(jfeature, "type", "Feature");
cJSON_AddItemToObject(jfeature, "geometry", jgeom);
nfeat++;
}
if (nfeat == 1) {
return jgeom;
} else {
return jlayer;
}
}
#else
// Convert `mapcache_extent` to `cJSON` structure embedding GeoJSON data
cJSON * mapcache_extent_to_cJSON(const mapcache_extent *extent)
{
cJSON * geojson = cJSON_CreateObject();
cJSON * jpolygon;
cJSON * jpoint;
cJSON_AddStringToObject(geojson, "type", "Polygon");
jpolygon = cJSON_AddArrayToObject(geojson, "coordinates");
jpoint = cJSON_AddArrayToObject(jpolygon, "");
cJSON_AddNumberToObject(jpoint, "", extent->minx);
cJSON_AddNumberToObject(jpoint, "", extent->miny);
jpoint = cJSON_CreateObject();
jpoint = cJSON_AddArrayToObject(jpolygon, "");
cJSON_AddNumberToObject(jpoint, "", extent->maxx);
cJSON_AddNumberToObject(jpoint, "", extent->miny);
jpoint = cJSON_CreateObject();
jpoint = cJSON_AddArrayToObject(jpolygon, "");
cJSON_AddNumberToObject(jpoint, "", extent->maxx);
cJSON_AddNumberToObject(jpoint, "", extent->maxy);
jpoint = cJSON_CreateObject();
jpoint = cJSON_AddArrayToObject(jpolygon, "");
cJSON_AddNumberToObject(jpoint, "", extent->minx);
cJSON_AddNumberToObject(jpoint, "", extent->maxy);
jpoint = cJSON_CreateObject();
jpoint = cJSON_AddArrayToObject(jpolygon, "");
cJSON_AddNumberToObject(jpoint, "", extent->minx);
cJSON_AddNumberToObject(jpoint, "", extent->miny);
return geojson;
}
#endif // USE_CLIPPERS
///////////////////////////////////////////////////////////////////////////////
//
// Operations on Mapcache SQLite files
//
///////////////////////////////////////////////////////////////////////////////
// Replace all occurrences of substr in string
char * str_replace_all(apr_pool_t *pool, const char *string,
const char *substr, const char *replacement)
{
char * replaced = apr_pstrdup(pool, string);
while (strstr(replaced, substr)) {
replaced = mapcache_util_str_replace(pool, string, substr, replacement);
}
return replaced;
}
// Build up actual SQLite filename from dbfile template
char * dbfilename(apr_pool_t * pool, char * template,
mapcache_tileset * tileset, mapcache_grid * grid,
apr_array_header_t * dimensions, apr_hash_t * fmt, int z,
int dbx, int dby, int xcount, int ycount, int top)
{
int tilx = dbx * xcount;
int tily = dby * ycount;
char * path = apr_pstrdup(pool, template);
if (!strstr(path, "{")) {
return path;
}
// Tileset and grid
path = str_replace_all(pool, path, "{tileset}", tileset->name);
path = str_replace_all(pool, path, "{grid}", grid->name);
// Dimensions: both {dim} and {dim:foo}
if (strstr(path, "{dim") && dimensions) {
char * dimstr = "";
int i = dimensions->nelts;
while(i--) {
mapcache_requested_dimension *entry;
const char * val;
char *solodim;
entry = APR_ARRAY_IDX(dimensions, i, mapcache_requested_dimension*);
val = mapcache_util_str_sanitize(pool, entry->cached_value, "/.", '#');
solodim = apr_pstrcat(pool, "{dim:", entry->dimension->name, "}", NULL);
dimstr = apr_pstrcat(pool, dimstr, "#", val, NULL);
if(strstr(path, solodim)) {
path = str_replace_all(pool, path, solodim, val);
}
}
path = str_replace_all(pool, path, "{dim}", dimstr);
}
// Zoom level
path = str_replace_all(pool, path, "{z}",
apr_psprintf(pool, apr_hash_get(fmt, "z", APR_HASH_KEY_STRING), z));
// X coordinate
if (xcount > 0) {
char * curfmt;
curfmt = apr_hash_get(fmt, "x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{x}",
apr_psprintf(pool, curfmt, tilx));
curfmt = apr_hash_get(fmt, "div_x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{div_x}",
apr_psprintf(pool, curfmt, dbx));
curfmt = apr_hash_get(fmt, "inv_x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_x}",
apr_psprintf(pool, curfmt, tilx));
curfmt = apr_hash_get(fmt, "inv_div_x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_div_x}",
apr_psprintf(pool, curfmt, dbx));
}
// Y coordinate
if (ycount > 0) {
char * curfmt;
curfmt = apr_hash_get(fmt, "y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{y}",
apr_psprintf(pool, curfmt, tily));
curfmt = apr_hash_get(fmt, "div_y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{div_y}",
apr_psprintf(pool, curfmt, dby));
curfmt = apr_hash_get(fmt, "inv_y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_y}",
apr_psprintf(pool, curfmt, tily));
curfmt = apr_hash_get(fmt, "inv_div_y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_div_y}",
apr_psprintf(pool, curfmt, dby));
}
// Z top
if (top > 0) {
char * curfmt;
curfmt = apr_hash_get(fmt, "top", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{top}",
apr_psprintf(pool, curfmt, top));
curfmt = apr_hash_get(fmt, "top_x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{top_x}",
apr_psprintf(pool, curfmt, dbx));
curfmt = apr_hash_get(fmt, "inv_top_x", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_top_x}",
apr_psprintf(pool, curfmt, dbx));
curfmt = apr_hash_get(fmt, "top_y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{top_y}",
apr_psprintf(pool, curfmt, dby));
curfmt = apr_hash_get(fmt, "inv_top_y", APR_HASH_KEY_STRING);
path = str_replace_all(pool, path, "{inv_top_y}",
apr_psprintf(pool, curfmt, dby));
}
return path;
}
// Query SQLite for getting tile count in specified area
void count_tiles_in_rectangle(
mapcache_context * ctx,
int z,
mapcache_extent_i til,
mapcache_tileset * tileset,
mapcache_grid_link * grid_link,
apr_array_header_t * dimensions,
const char * dbfile,
const char * count_query,
int *tmax,
int *tcached
)
{
mapcache_grid *grid = grid_link->grid;
sqlite3 * db;
sqlite3_stmt * res;
int rc, idx;
int count;
*tcached = 0;
*tmax = (til.maxx-til.minx+1) * (til.maxy-til.miny+1);
rc = sqlite3_open_v2(dbfile, &db, SQLITE_OPEN_READONLY, NULL);
if (rc != SQLITE_OK) {
sqlite3_close(db);
return;
}
sqlite3_busy_timeout(db, 5000);
rc = sqlite3_prepare_v2(db, count_query, -1, &res, 0);
if (rc != SQLITE_OK) {
ctx->set_error(ctx, 500, "SQLite failed on %s: '%s'",
dbfile, sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
idx = sqlite3_bind_parameter_index(res, ":minx");
if (idx) sqlite3_bind_int(res, idx, til.minx);
idx = sqlite3_bind_parameter_index(res, ":miny");
if (idx) sqlite3_bind_int(res, idx, til.miny);
idx = sqlite3_bind_parameter_index(res, ":maxx");
if (idx) sqlite3_bind_int(res, idx, til.maxx);
idx = sqlite3_bind_parameter_index(res, ":maxy");
if (idx) sqlite3_bind_int(res, idx, til.maxy);
idx = sqlite3_bind_parameter_index(res, ":z");
if (idx) sqlite3_bind_int(res, idx, z);
idx = sqlite3_bind_parameter_index(res, ":grid");
if (idx) sqlite3_bind_text(res, idx, grid->name, -1, SQLITE_STATIC);
idx = sqlite3_bind_parameter_index(res, ":tileset");
if (idx) sqlite3_bind_text(res, idx, tileset->name, -1, SQLITE_STATIC);
idx = sqlite3_bind_parameter_index(res, ":dim");
if (idx) {
char * dim = "";
if (dimensions) {
mapcache_tile tile;
tile.dimensions = dimensions;
dim = mapcache_util_get_tile_dimkey(ctx, &tile, NULL, NULL);
}
sqlite3_bind_text(res, idx, dim, -1, SQLITE_STATIC);
}
rc = sqlite3_step(res);
switch (rc) {
case SQLITE_ROW:
count = strtol((const char*)sqlite3_column_text(res, 0), NULL, 10);
break;
case SQLITE_DONE:
ctx->set_error(ctx, 500, "SQLite returned no tile count (%s)", dbfile);
count = 0;
break;
default:
ctx->set_error(ctx, 500, "SQLite failed on %s: '%s'",
dbfile, sqlite3_errmsg(db));
count = 0;
}
sqlite3_finalize(res);
sqlite3_close(db);
*tcached = count;
}
#ifdef USE_CLIPPERS
// Count tiles in arbitrary region geometry for given zoom level, iterating
// over supplied bounding box expressed in tiles
void count_tiles_in_region(
mapcache_context *c,
int zl,
mapcache_extent_i til_bbox,
mapcache_tileset *t,
mapcache_grid_link *gl,
apr_array_header_t *d,
const GEOSPreparedGeometry *pg,
int file_exists,
int *tmax,
int *tcached
)
{
int tx, ty;
GEOSGeometry *tile_geom = NULL;
// Iterate over tiles within supplied bbox
*tmax = *tcached = 0;
for (tx = til_bbox.minx ; tx <= til_bbox.maxx ; tx++) {
for (ty = til_bbox.miny ; ty <= til_bbox.maxy ; ty++) {
mapcache_extent tile_bbox;
// Compute tile bounding box expressed in grid units
mapcache_grid_get_tile_extent(c, gl->grid, tx, ty, zl, &tile_bbox);
if (!tile_geom) {
tile_geom = mapcache_extent_to_GEOSGeometry(&tile_bbox);
} else {
update_GEOSGeometry_with_mapcache_extent(tile_geom, &tile_bbox);
}
// Count tile if it is within region of interest
if (GEOSPreparedIntersects(pg, tile_geom) == 1) {
int tile_exists = FALSE;
mapcache_tile *tile;
(*tmax)++;
// Check whether tile is present in cache
if (file_exists) {
tile = mapcache_tileset_tile_create(c->pool, t, gl);
tile->x = tx;
tile->y = ty;
tile->z = zl;
tile->dimensions = d;
tile_exists = mapcache_cache_tile_exists(c, t->_cache, tile);
if (tile_exists) (*tcached)++;
}
}
}
}
GEOSGeom_destroy(tile_geom);
}
#endif // USE_CLIPPERS
///////////////////////////////////////////////////////////////////////////////
//
// Program entry point
//
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char * argv[])
{
mapcache_context ctx;
apr_getopt_t * opt;
int status;
int optk;
const char * optv;
int json_output = TRUE;
int show_progress = TRUE;
cJSON *jreport, *jitem, *jregion, *jzooms, *jzoom, *jfiles, *jfile;
const char * config_file = NULL;
const char * tileset_name = NULL;
const char * grid_name = NULL;
const char * dim_spec = NULL;
const char * count_query = NULL;
const char * extent = NULL;
const char * ogr_file = NULL;
const char * ogr_layer = NULL;
const char * ogr_where = NULL;
const char * ogr_sql = NULL;
const char * zoom = NULL;
#ifdef USE_CLIPPERS
GEOSGeometry *region_geom;
GEOSGeometry *grid_geom;
const GEOSPreparedGeometry *region_prepgeom = NULL;
#else // Use region_bbox instead of region_geom
#endif // USE_CLIPPERS
mapcache_tileset * tileset = NULL;
mapcache_grid * grid = NULL;
mapcache_grid_link * grid_link;
apr_array_header_t * dimensions = NULL;
struct cache_info {
ezxml_t node;
mapcache_cache * cache;
int minzoom, maxzoom;
char * dbfile;
apr_hash_t * formats;
int xcount, ycount, top;
} *cache;
apr_array_header_t * caches = NULL;
int i, ix, iy, iz;
ezxml_t doc, node;
ezxml_t dbfile_node = NULL;
char * text;
apr_hash_index_t * hi;
mapcache_extent region_bbox = { 0, 0, 0, 0 };
double * list = NULL;
int nelts;
int minzoom = 0, maxzoom = 0;
int64_t tiles_max_in_cache = 0;
int64_t tiles_cached_in_cache = 0;
apr_off_t size_of_cache = 0;
int64_t tiles_in_cache = 0;
apr_hash_t * db_files = NULL;
int cid;
int nb_missing_files = 0;
int report_missing_files = TRUE;
/////////////////////////////////////////////////////////////////////////////
// Initialize Apache, GEOS, OGR, cJSON and Mapcache
//
apr_initialize();
#ifdef USE_CLIPPERS
initGEOS(notice, log_and_exit);
OGRRegisterAll();
#endif // USE_CLIPPERS
apr_pool_create(&ctx.pool, NULL);
_create_json_pool(ctx.pool);
mapcache_context_init(&ctx);
ctx.config = mapcache_configuration_create(ctx.pool);
ctx.log = mapcache_log;
mapcache_cache_child_init(&ctx,ctx.config,ctx.pool);
if (GC_HAS_ERROR(&ctx)) goto failure;
mapcache_connection_pool_create(ctx.config, &ctx.connection_pool, ctx.pool);
/////////////////////////////////////////////////////////////////////////////
// Parse command-line options
//
apr_getopt_init(&opt, ctx.pool, argc, (const char*const*)argv);
while ((status = apr_getopt_long(opt, optlist, &optk, &optv)) == APR_SUCCESS)
{
switch (optk) {
case 'h': // --help
usage(ctx.pool, argv[0], NULL);
goto success;
break;
case 'c': // --config
config_file = optv;
break;
case 't': // --tileset
tileset_name = optv;
break;
case 'g': // --grid
grid_name = optv;
break;
case 'D': // --dimension
if (!dim_spec) {
dim_spec = optv;
} else {
dim_spec = apr_pstrcat(ctx.pool, dim_spec, ":", optv, NULL);
}
break;
case 'q': // --query
count_query = optv;
break;
case 'e': // --extent ,,,
extent = optv;
break;
case 'd': // --ogr-datasource
ogr_file = optv;
break;
case 'l': // --ogr-layer
ogr_layer = optv;
break;
case 'w': // --ogr-where
ogr_where = optv;
break;
case 's': // --ogr-sql
ogr_sql = optv;
break;
case 'z': // --zoom [,]
zoom = optv;
break;
case 'o': // --short-output
report_missing_files = FALSE;
break;
}
}
if (status != APR_EOF) {
usage(ctx.pool, argv[0], "Bad options");
goto failure;
}
/////////////////////////////////////////////////////////////////////////////
// Load Mapcache configuration file in Mapcache internal data structure
//
if (!config_file) {
usage(ctx.pool, argv[0], "Configuration file has not been specified");
goto failure;
}
mapcache_configuration_parse(&ctx, config_file, ctx.config, 0);
if (GC_HAS_ERROR(&ctx)) goto failure;
/////////////////////////////////////////////////////////////////////////////
// Retrieve tileset information
//
if (!tileset_name) {
usage(ctx.pool, argv[0], "Tileset has not been specified");
goto failure;
}
tileset = mapcache_configuration_get_tileset(ctx.config, tileset_name);
if (!tileset) {
ctx.set_error(&ctx, 500,
"Tileset \"%s\" has not been found in configuration \"%s\"",
tileset_name, config_file);
goto failure;
}
/////////////////////////////////////////////////////////////////////////////
// Retrieve grid information
//
if (!grid_name) {
usage(ctx.pool, argv[0], "Grid has not been specified");
goto failure;
}
for (i=0 ; igrid_links->nelts ; i++) {
grid_link = APR_ARRAY_IDX(tileset->grid_links, i, mapcache_grid_link*);
if (strcmp(grid_link->grid->name, grid_name)==0) {
grid = grid_link->grid;
break;
}
}
if (!grid) {
ctx.set_error(&ctx, 500,
"Grid \"%s\" has not been found in tileset \"%s\"",
grid_name, tileset->name);
goto failure;
}
/////////////////////////////////////////////////////////////////////////////
// Retrieve region of interest geometry, either from --extent or from
// --ogr-... option group
//
if (extent && ogr_file) {
ctx.set_error(&ctx, 500,
"Extent and OGR Data Source are mutually exclusive");
goto failure;
}
if (!ogr_file && (ogr_sql || ogr_layer || ogr_where)) {
ctx.set_error(&ctx, 500,
"OGR Data Source is required with other OGR related options");
goto failure;
}
if (ogr_sql && (ogr_layer || ogr_where)) {
ctx.set_error(&ctx, 500,
"--ogr-sql cannot be used with --ogr-layer or --ogr-where");
goto failure;
}
// Region of interest is specified with --extent
if (extent) {
#ifdef USE_CLIPPERS
GEOSGeometry *temp;
#endif
if (mapcache_util_extract_double_list(&ctx, extent, ",", &list, &nelts)
!= MAPCACHE_SUCCESS || nelts != 4)
{
usage(ctx.pool, argv[0], "Failed to parse extent: \"%s\"", extent);
goto failure;
}
region_bbox.minx = list[0];
region_bbox.miny = list[1];
region_bbox.maxx = list[2];
region_bbox.maxy = list[3];
// Swap bounds if inverted
if (region_bbox.minx > region_bbox.maxx) {
double swap = region_bbox.minx;
region_bbox.minx = region_bbox.maxx;
region_bbox.maxx = swap;
}
if (region_bbox.miny > region_bbox.maxy) {
double swap = region_bbox.miny;
region_bbox.miny = region_bbox.maxy;
region_bbox.maxy = swap;
}
#ifdef USE_CLIPPERS
temp = mapcache_extent_to_GEOSGeometry(®ion_bbox);
region_geom = temp;
#else // Use region_bbox instead of region_geom
#endif
}
#ifdef USE_CLIPPERS
// Region of interest is specified with OGR
if (ogr_file) {
OGRDataSourceH ogr = NULL;
OGRLayerH layer = NULL;
OGRFeatureH feature;
GEOSWKTReader *geoswktreader;
int nFeatures;
ogr = OGROpen(ogr_file, FALSE, NULL);
if (!ogr) {
ctx.set_error(&ctx, 500, "Failed to open OGR data source: %s", ogr_file);
goto failure;
}
// Get layer from OGR data source
if (ogr_sql) {
// Get layer from SQL
layer = OGR_DS_ExecuteSQL(ogr,ogr_sql, NULL, NULL);
if (!layer) {
ctx.set_error(&ctx, 500, "Failed to get OGR layer from OGR SQL query");
}
} else {
// Get layer from OGR layer / OGR where
int nlayers = OGR_DS_GetLayerCount(ogr);
if (nlayers > 1 && !ogr_layer) {
ctx.set_error(&ctx, 500, "OGR data source has more than one layer"
" but OGR layer has not been specified");
goto failure;
} else if (ogr_layer) {
layer = OGR_DS_GetLayerByName(ogr, ogr_layer);
} else {
layer = OGR_DS_GetLayer(ogr, 0);
}
if (!layer) {
ctx.set_error(&ctx, 500, "Failed to find OGR layer");
goto failure;
}
if (ogr_where) {
if (OGR_L_SetAttributeFilter(layer, ogr_where) != OGRERR_NONE) {
ctx.set_error(&ctx, 500, "Failed to filter with --ogr-where %s",
ogr_where);
goto failure;
}
}
}
OGR_L_ResetReading(layer);
// Get geometry from layer
nFeatures = OGR_L_GetFeatureCount(layer, TRUE);
if (nFeatures == 0) {
ctx.set_error(&ctx, 500, "Failed to find features in OGR layer");
goto failure;
}
region_geom = GEOSGeom_createEmptyPolygon();
geoswktreader = GEOSWKTReader_create();
nFeatures = 0;
while ((feature = OGR_L_GetNextFeature(layer))) {
char *wkt;
GEOSGeometry *geos_geom, *temp;
OGREnvelope ogr_extent;
OGRGeometryH ogr_geom = OGR_F_GetGeometryRef(feature);
if (!ogr_geom || !OGR_G_IsValid(ogr_geom)) continue;
OGR_G_ExportToWkt(ogr_geom,&wkt);
geos_geom = GEOSWKTReader_read(geoswktreader,wkt);
CPLFree(wkt);
OGR_G_GetEnvelope(ogr_geom, &ogr_extent);
if (nFeatures == 0) {
region_bbox.minx = ogr_extent.MinX;
region_bbox.miny = ogr_extent.MinY;
region_bbox.maxx = ogr_extent.MaxX;
region_bbox.maxy = ogr_extent.MaxY;
} else {
region_bbox.minx = fminl(region_bbox.minx, ogr_extent.MinX);
region_bbox.miny = fminl(region_bbox.miny, ogr_extent.MinY);
region_bbox.maxx = fmaxl(region_bbox.maxx, ogr_extent.MaxX);
region_bbox.maxy = fmaxl(region_bbox.maxy, ogr_extent.MaxY);
}
nFeatures++;
temp = GEOSUnion(region_geom, geos_geom);
GEOSGeom_destroy(region_geom);
region_geom = temp;
}
GEOSWKTReader_destroy(geoswktreader);
}
#endif // USE_CLIPPERS
// Set region to grid extent when no region has been provided
if (!extent && !ogr_file) {
#ifdef USE_CLIPPERS
GEOSGeometry *temp;
#endif
region_bbox.minx = grid->extent.minx;
region_bbox.miny = grid->extent.miny;
region_bbox.maxx = grid->extent.maxx;
region_bbox.maxy = grid->extent.maxy;
#ifdef USE_CLIPPERS
temp = mapcache_extent_to_GEOSGeometry(®ion_bbox);
region_geom = temp;
#else // Use region_bbox instead of region_geom
#endif
}
// Region of interest must be within grid extent
#ifdef USE_CLIPPERS
region_prepgeom = GEOSPrepare(region_geom);
grid_geom = mapcache_extent_to_GEOSGeometry(&(grid->extent));
if (GEOSPreparedWithin(region_prepgeom, grid_geom) != 1) {
#else // Use region_bbox instead of region_geom
if ( (region_bbox.minx < grid->extent.minx)
|| (region_bbox.miny < grid->extent.miny)
|| (region_bbox.maxx > grid->extent.maxx)
|| (region_bbox.maxy > grid->extent.maxy))
{
#endif // USE_CLIPPERS
ctx.set_error(&ctx, 500,
"Requested geometry is not contained within Grid extent: "
"[ %.18g, %.18g, %.18g, %.18g ]\n", grid->extent.minx,
grid->extent.miny, grid->extent.maxx, grid->extent.maxy);
goto failure;
}
/////////////////////////////////////////////////////////////////////////////
// Load MapCache configuration again, this time as an XML document, in order
// to gain access to settings that are unreacheable from Mapcache API
//
doc = ezxml_parse_file(config_file);
/////////////////////////////////////////////////////////////////////////////
// Retrieve cache information from XML document
//
// Create table of caches
if (!caches) caches = apr_array_make(ctx.pool, 1, sizeof(void*));
// Retrieve cache element in XML configuration
cache = apr_palloc(ctx.pool, sizeof(struct cache_info));
cache->cache = tileset->_cache;
cache->node = NULL;
for (node = ezxml_child(doc, "cache") ; node ; node = node->next) {
if (strcmp(ezxml_attr(node, "name"), cache->cache->name) == 0) {
cache->node = node;
break;
}
}
// Retrieve individuals caches in the composite
if (cache->cache->type == MAPCACHE_CACHE_COMPOSITE) {
for (node = ezxml_child(cache->node, "cache") ; node ; node = node->next) {
struct cache_info * c = apr_palloc(ctx.pool, sizeof(struct cache_info));
const char * val;
ezxml_t n;
// Read min-zoom and max-zoom attributes of reference
c->minzoom = 0;
c->maxzoom = INT_MAX;
val = ezxml_attr(node, "min-zoom");
if (val) c->minzoom = (int)strtol(val, NULL, 10);
val = ezxml_attr(node, "max-zoom");
if (val) c->maxzoom = (int)strtol(val, NULL, 10);
// Retrieve individual cache element in XML configuration
c->cache = mapcache_configuration_get_cache(ctx.config, node->txt);
c->node = NULL;
for (n = ezxml_child(doc, "cache") ; n ; n = n->next) {
if (strcmp(ezxml_attr(n, "name"), c->cache->name) == 0) {
c->node = n;
break;
}
}
APR_ARRAY_PUSH(caches, struct cache_info*) = c;
}
}
else {
APR_ARRAY_PUSH(caches, struct cache_info*) = cache;
}
// Retrieve information on all stored caches
for ( cid=0 ; cid < caches->nelts ; cid++ ) {
struct cache_info * c = APR_ARRAY_IDX(caches, cid, struct cache_info*);
// Only SQLite caches are handled
if (c->cache->type != MAPCACHE_CACHE_SQLITE) {
ctx.set_error(&ctx, 500,
"cache \"%s\" of tileset \"%s\" is not of type SQLite",
c->cache->name, tileset->name);
goto failure;
}
// Read element from
dbfile_node = ezxml_child(c->node, "dbfile");
c->dbfile = dbfile_node->txt;
if (!c->dbfile) {
ctx.set_error(&ctx, 500,
"Failed to parse tag of cache \"%s\"", c->cache->name);
goto failure;
}
// Read formats of x,y,z placeholders in dbfile template
c->formats = apr_hash_make(ctx.pool);
apr_hash_set(c->formats, "x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "y", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "z", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_y", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "div_x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "div_y", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_div_x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_div_y", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "top", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "top_x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "top_y", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_top_x", APR_HASH_KEY_STRING, "(not set)");
apr_hash_set(c->formats, "inv_top_y", APR_HASH_KEY_STRING, "(not set)");
for (hi = apr_hash_first(ctx.pool, c->formats)
; hi
; hi = apr_hash_next(hi))
{
const char *key, *val, *attr;
apr_hash_this(hi, (const void**)&key, NULL, (void**)&val);
attr = apr_pstrcat(ctx.pool, key, "_fmt", NULL);
val = ezxml_attr(dbfile_node, attr);
if (!val) val = "%d";
apr_hash_set(c->formats, key, APR_HASH_KEY_STRING, val);
}
// Read xcount and ycount
c->xcount = c->ycount = -1;
node = ezxml_child(c->node, "xcount");
text = NULL;
if (node) text = node->txt;
if (text) c->xcount = (int)strtol(text, NULL, 10);
node = ezxml_child(c->node, "ycount");
text = NULL;
if (node) text = node->txt;
if (text) c->ycount = (int)strtol(text, NULL, 10);
// Read top
c->top = -1;
node = ezxml_child(c->node, "top");
text = NULL;
if (node) text = node->txt;
if (text) c->top = (int)strtol(text, NULL, 10);
}
/////////////////////////////////////////////////////////////////////////////
// Retrieve dimensions information
//
if (tileset->dimensions) {
// Set up dimensions with default values
dimensions = apr_array_make(ctx.pool, tileset->dimensions->nelts,
sizeof(mapcache_requested_dimension*));
for ( i=0 ; i < tileset->dimensions->nelts ; i++ ) {
mapcache_dimension * dim;
mapcache_requested_dimension * reqdim;
dim = APR_ARRAY_IDX(tileset->dimensions, i, mapcache_dimension*);
reqdim = apr_pcalloc(ctx.pool, sizeof(mapcache_requested_dimension));
reqdim->dimension = dim;
reqdim->requested_value = dim->default_value;
reqdim->cached_value = dim->default_value;
APR_ARRAY_PUSH(dimensions, mapcache_requested_dimension*) = reqdim;
}
// Update dimensions with values specified with -D command line option
// syntax is: "dim1=value1:dim2=value2:..."
if (dim_spec) {
char * ds = apr_pstrdup(ctx.pool, dim_spec);
char *kvp, *last;
for (kvp=apr_strtok(ds, ":", &last)
; kvp ; kvp = apr_strtok(NULL, ":", &last))
{
char *key, *val, *sav;
key = apr_strtok(kvp, "=", &sav);
val = apr_strtok(NULL, "=", &sav);
if (!key || !val) {
usage(ctx.pool, argv[0],
"Can't parse dimension settings: %s", dim_spec);
goto failure;
}
mapcache_set_requested_dimension(&ctx, dimensions, key, val);
mapcache_set_cached_dimension(&ctx, dimensions, key, val);
if (GC_HAS_ERROR(&ctx)) goto failure;
}
}
// Check that dimension values are valid
for ( i=0 ; i < dimensions->nelts ; i++) {
mapcache_requested_dimension *entry;
apr_array_header_t * vals;
entry = APR_ARRAY_IDX(dimensions, i, mapcache_requested_dimension*);
vals = mapcache_dimension_get_entries_for_value(&ctx,
entry->dimension, entry->requested_value, tileset, NULL, grid);
if (GC_HAS_ERROR(&ctx)) goto failure;
if (!vals || vals->nelts == 0) {
ctx.set_error(&ctx, 500,
"invalid value \"%s\" for dimension \"%s\"\n",
entry->requested_value, entry->dimension->name);
goto failure;
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Set default query for counting tiles in a rectangular part of a SQLite
// cache file
//
if (!count_query) {
count_query = "SELECT count(rowid)"
" FROM tiles"
" WHERE (x between :minx and :maxx)"
" AND (y between :miny and :maxy)"
" AND (z=:z)"
" AND tileset=:tileset AND grid=:grid AND dim=:dim";
}
/////////////////////////////////////////////////////////////////////////////
// Retrieve zoom level interval (defaults to 0)
//
if (zoom) {
minzoom = strtol(zoom, &text, 10);
maxzoom = minzoom;
if (*text == ',') {
maxzoom = strtol(text+1, &text, 10);
}
if (*text != '\0') {
usage(ctx.pool, argv[0], "Bad int format for zoom level: %s", zoom);
goto failure;
}
if (minzoom > maxzoom) {
int swap = minzoom;
minzoom = maxzoom;
maxzoom = swap;
}
if (minzoom < 0) {
ctx.set_error(&ctx, 500,
"Zoom level %d not in valid interval [ %d, %d ]",
minzoom, 0, grid->nlevels-1);
goto failure;
}
if (maxzoom >= grid->nlevels) {
ctx.set_error(&ctx, 500,
"Zoom level %d not in valid interval [ %d, %d ]",
maxzoom, 0, grid->nlevels-1);
goto failure;
}
}
/////////////////////////////////////////////////////////////////////////////
// Report global identification information
//
if (json_output) {
jreport = cJSON_CreateObject();
cJSON_AddStringToObject(jreport, "layer", tileset->name);
cJSON_AddStringToObject(jreport, "grid", grid->name);
cJSON_AddStringToObject(jreport, "unit",
grid->unit==MAPCACHE_UNIT_METERS? "m":
grid->unit==MAPCACHE_UNIT_DEGREES?"dd":"ft");
jregion = cJSON_CreateObject();
cJSON_AddItemToObject(jreport, "region", jregion);
jitem = cJSON_AddArrayToObject(jregion, "bounding_box");
cJSON_AddNumberToObject(jitem, "", region_bbox.minx);
cJSON_AddNumberToObject(jitem, "", region_bbox.miny);
cJSON_AddNumberToObject(jitem, "", region_bbox.maxx);
cJSON_AddNumberToObject(jitem, "", region_bbox.maxy);
#ifdef USE_CLIPPERS
cJSON_AddItemToObject(jregion, "geometry",
GEOSGeometry_to_cJSON(region_geom));
#else // Use region_bbox instead of region_geom
cJSON_AddItemToObject(jregion, "geometry",
mapcache_extent_to_cJSON(®ion_bbox));
#endif // USE_CLIPPERS
jzooms = cJSON_AddArrayToObject(jreport, "zoom_levels");
}
/////////////////////////////////////////////////////////////////////////////
// Iterate over all tiles of all DB files of all requested zoom levels within
// region of interest
//
// Iterate over all requested zoom levels
for (iz = minzoom ; iz <= maxzoom ; iz ++) {
int64_t tiles_max_in_level = 0;
int64_t tiles_cached_in_level = 0;
mapcache_extent_i til_region_bbox;
mapcache_extent_i db_region_bbox;
int dbx_has_inv = FALSE;
int dby_has_inv = FALSE;
int file_zoom_level;
// Select cache according to zoom level
for ( cid=0 ; cid < caches->nelts ; cid++ ) {
cache = APR_ARRAY_IDX(caches, cid, struct cache_info*);
if ((iz >= cache->minzoom) && (iz <= cache->maxzoom)) break;
}
if (cache->cache->type != MAPCACHE_CACHE_SQLITE) {
ctx.set_error(&ctx, 500,
"cache \"%s\" of tileset \"%s\" is not of type SQLite",
cache->cache->name, tileset->name);
goto failure;
}
// Report identification information for current zoom level
if (json_output) {
jzoom = cJSON_CreateObject();
cJSON_AddItemToObject(jzooms, "", jzoom);
cJSON_AddNumberToObject(jzoom, "level", iz);
jfiles = cJSON_AddArrayToObject(jzoom, "files");
}
// Compute region bounding box expressed in tiles and in DB files for the
// current zoom level
file_zoom_level = iz;
if (cache->top > 0) file_zoom_level = cache->top;
mapcache_grid_get_xy(&ctx, grid, region_bbox.minx, region_bbox.miny,
file_zoom_level, &(til_region_bbox.minx), &(til_region_bbox.miny));
mapcache_grid_get_xy(&ctx, grid, region_bbox.maxx, region_bbox.maxy,
file_zoom_level, &(til_region_bbox.maxx), &(til_region_bbox.maxy));
if (til_region_bbox.minx > til_region_bbox.maxx) {
int swap = til_region_bbox.maxx;
til_region_bbox.maxx = til_region_bbox.minx;
til_region_bbox.minx = swap;
}
if (til_region_bbox.miny > til_region_bbox.maxy) {
int swap = til_region_bbox.maxy;
til_region_bbox.maxy = til_region_bbox.miny;
til_region_bbox.miny = swap;
}
dbx_has_inv = strstr(cache->dbfile,"{inv_x}")
|| strstr(cache->dbfile,"{inv_div_x}")
|| strstr(cache->dbfile,"{inv_top_x}");
dby_has_inv = strstr(cache->dbfile,"{inv_y}")
|| strstr(cache->dbfile,"{inv_div_y}")
|| strstr(cache->dbfile,"{inv_top_y}");
if (cache->top > 0) {
if (dbx_has_inv) {
db_region_bbox.minx = grid->levels[cache->top]->maxx-1 - til_region_bbox.maxx;
db_region_bbox.maxx = grid->levels[cache->top]->maxx-1 - til_region_bbox.minx;
} else {
db_region_bbox.minx = til_region_bbox.minx;
db_region_bbox.maxx = til_region_bbox.maxx;
}
if (dby_has_inv) {
db_region_bbox.miny = grid->levels[cache->top]->maxy-1 - til_region_bbox.maxy;
db_region_bbox.maxy = grid->levels[cache->top]->maxy-1 - til_region_bbox.miny;
} else {
db_region_bbox.miny = til_region_bbox.miny;
db_region_bbox.maxy = til_region_bbox.maxy;
}
} else if ((cache->xcount > 0) && (cache->ycount > 0)) {
if (dbx_has_inv) {
int inv_minx = grid->levels[iz]->maxx - til_region_bbox.minx;
int inv_maxx = grid->levels[iz]->maxx - til_region_bbox.maxx;
db_region_bbox.minx = floor(inv_maxx/cache->ycount);
db_region_bbox.maxx = floor(inv_minx/cache->ycount);
} else {
db_region_bbox.minx = floor(til_region_bbox.minx/cache->xcount);
db_region_bbox.maxx = floor(til_region_bbox.maxx/cache->xcount);
}
if (dby_has_inv) {
int inv_miny = grid->levels[iz]->maxy - til_region_bbox.miny;
int inv_maxy = grid->levels[iz]->maxy - til_region_bbox.maxy;
db_region_bbox.miny = floor(inv_maxy/cache->ycount);
db_region_bbox.maxy = floor(inv_miny/cache->ycount);
} else {
db_region_bbox.miny = floor(til_region_bbox.miny/cache->ycount);
db_region_bbox.maxy = floor(til_region_bbox.maxy/cache->ycount);
}
} else {
db_region_bbox.minx = 0;
db_region_bbox.miny = 0;
db_region_bbox.maxx = 0;
db_region_bbox.maxy = 0;
}
// Iterate over DB files of current level within region bounding box
if (!db_files) db_files = apr_hash_make(ctx.pool);
for (ix = db_region_bbox.minx ; ix <= db_region_bbox.maxx ; ix++) {
for (iy = db_region_bbox.miny ; iy <= db_region_bbox.maxy ; iy++) {
int tiles_max_in_file = 0;
int tiles_cached_in_file = 0;
char * file_name;
apr_status_t file_open_report;
apr_file_t * filehandle;
apr_finfo_t fileinfo;
mapcache_extent_i til_file_bbox;
mapcache_extent file_bbox;
mapcache_extent temp_bbox;
mapcache_extent region_in_file_bbox;
#ifdef USE_CLIPPERS
GEOSGeometry *file_geom;
GEOSGeometry *temp_geom;
GEOSGeometry *region_in_file_geom;
const GEOSGeometry *temp_ring;
int npoints, p;
#endif // USE_CLIPPERS
mapcache_extent_i til_region_in_file_bbox;
int region_in_file_is_rectangle = FALSE;
int region_in_file_is_empty = FALSE;
apr_off_t *sizeref;
double res;
// Display progression
if (show_progress) {
double incz = 1.0 / (double)(maxzoom - minzoom + 1);
double incx = incz / (double)(db_region_bbox.maxx
- db_region_bbox.minx + 1);
double incy = incx / (double)(db_region_bbox.maxy
- db_region_bbox.miny + 1);
double progz = (double)(iz - minzoom) * incz;
double progx = (double)(ix - db_region_bbox.minx) * incx;
double progy = (double)(iy - db_region_bbox.miny) * incy;
fprintf(stderr, "\033[2K In progress (z:%d x:%d y:%d): %.3f%% done\r",
iz, ix, iy, (progz + progx + progy) * 100.0);
fflush(stderr);
}
// Retrieve DB file name and check for its existence (read access)
file_name = dbfilename(ctx.pool, cache->dbfile, tileset, grid,
dimensions, cache->formats, iz, ix, iy, cache->xcount,
cache->ycount, cache->top);
// Unless this has already been done on this file,
// Retrieve file size and count cached tiles regardless the region of
// interest (for average tile size estimation)
fileinfo.size = 0;
sizeref = apr_hash_get(db_files, file_name, APR_HASH_KEY_STRING);
if (sizeref) {
fileinfo.size = *sizeref;
} else {
file_open_report = apr_file_open(&filehandle, file_name,
APR_FOPEN_READ|APR_FOPEN_BINARY, APR_FPROT_OS_DEFAULT, ctx.pool);
if (file_open_report == APR_SUCCESS) {
int level;
// Retrieve file size
apr_file_info_get(&fileinfo, APR_FINFO_SIZE, filehandle);
apr_file_close(filehandle);
sizeref = apr_pcalloc(ctx.pool, sizeof(apr_off_t));
*sizeref = fileinfo.size;
apr_hash_set(db_files, file_name, APR_HASH_KEY_STRING, sizeref);
size_of_cache += fileinfo.size;
// Retrieve total number of cached tiles in file
for (level = 0 ; level < grid->nlevels ; level++) {
int tmpmax, tmpcached;
const mapcache_extent_i full_extent = { 0, 0, INT_MAX, INT_MAX };
count_tiles_in_rectangle(&ctx, level, full_extent, tileset,
grid_link, dimensions, file_name, count_query, &tmpmax,
&tmpcached);
if (GC_HAS_ERROR(&ctx)) goto failure;
tiles_in_cache += tmpcached;
}
}
else
{
nb_missing_files++ ;
}
}
// Compute file bounding box expressed in tiles
if (cache->top > 0) {
if (dbx_has_inv) {
til_file_bbox.minx = grid->levels[cache->top]->maxx-1 - ix;
til_file_bbox.maxx = til_file_bbox.minx;
} else {
til_file_bbox.minx = ix;
til_file_bbox.maxx = til_file_bbox.minx;
}
if (dby_has_inv) {
til_file_bbox.miny = grid->levels[cache->top]->maxy-1 - iy;
til_file_bbox.maxy = til_file_bbox.miny;
} else {
til_file_bbox.miny = iy;
til_file_bbox.maxy = til_file_bbox.miny;
}
} else if ((cache->xcount > 0) && (cache->ycount > 0)) {
if (dbx_has_inv) {
til_file_bbox.maxx = grid->levels[iz]->maxx-1 - ix * cache->xcount;
til_file_bbox.minx = til_file_bbox.maxx + cache->xcount + 1;
} else {
til_file_bbox.minx = ix * cache->xcount;
til_file_bbox.maxx = til_file_bbox.minx + cache->xcount - 1;
}
if (dby_has_inv) {
til_file_bbox.maxy = grid->levels[iz]->maxy-1 - iy * cache->ycount;
til_file_bbox.miny = til_file_bbox.maxy - cache->ycount + 1;
} else {
til_file_bbox.miny = iy * cache->ycount;
til_file_bbox.maxy = til_file_bbox.miny + cache->ycount - 1;
}
if (til_file_bbox.minx < 0) til_file_bbox.minx = 0;
if (til_file_bbox.miny < 0) til_file_bbox.miny = 0;
if (til_file_bbox.maxx >= grid->levels[iz]->maxx) {
til_file_bbox.maxx = grid->levels[iz]->maxx - 1;
}
if (til_file_bbox.maxy >= grid->levels[iz]->maxy) {
til_file_bbox.maxy = grid->levels[iz]->maxy - 1;
}
} else {
til_file_bbox.minx = 0;
til_file_bbox.miny = 0;
til_file_bbox.maxx = grid->levels[iz]->maxx - 1;
til_file_bbox.maxy = grid->levels[iz]->maxy - 1;
}
// Compute file bounding box expressed in grid units for the current
// zoom level
mapcache_grid_get_tile_extent(&ctx, grid, til_file_bbox.minx,
til_file_bbox.miny, file_zoom_level, &temp_bbox);
if (GC_HAS_ERROR(&ctx)) goto failure;
file_bbox.minx = temp_bbox.minx;
file_bbox.miny = temp_bbox.miny;
mapcache_grid_get_tile_extent(&ctx, grid, til_file_bbox.maxx,
til_file_bbox.maxy, file_zoom_level, &temp_bbox);
if (GC_HAS_ERROR(&ctx)) goto failure;
file_bbox.maxx = temp_bbox.maxx;
file_bbox.maxy = temp_bbox.maxy;
if (file_bbox.minx > file_bbox.maxx) {
int swap = file_bbox.maxx;
file_bbox.maxx = file_bbox.minx;
file_bbox.minx = swap;
}
if (file_bbox.miny > file_bbox.maxy) {
int swap = file_bbox.maxy;
file_bbox.maxy = file_bbox.miny;
file_bbox.miny = swap;
}
// Compute part of region of interest within file bounding box
#ifdef USE_CLIPPERS
file_geom = mapcache_extent_to_GEOSGeometry(&file_bbox);
region_in_file_geom = GEOSIntersection(region_geom, file_geom);
region_in_file_is_empty = GEOSisEmpty(region_in_file_geom);
#else // use _bbox instead of _geom
region_in_file_is_rectangle = TRUE;
region_in_file_bbox.minx = fmaxl(region_bbox.minx, file_bbox.minx);
region_in_file_bbox.maxx = fminl(region_bbox.maxx, file_bbox.maxx);
if (region_in_file_bbox.minx > region_in_file_bbox.maxx) {
region_in_file_bbox.minx = region_in_file_bbox.maxx = 0;
region_in_file_is_empty = TRUE;
}
region_in_file_bbox.miny = fmaxl(region_bbox.miny, file_bbox.miny);
region_in_file_bbox.maxy = fminl(region_bbox.maxy, file_bbox.maxy);
if (region_in_file_bbox.miny > region_in_file_bbox.maxy) {
region_in_file_bbox.miny = region_in_file_bbox.maxy = 0;
region_in_file_is_empty = TRUE;
}
#endif // USE_CLIPPERS
// Jump to next file if this one is outside the region of interest
if (region_in_file_is_empty) continue;
#ifdef USE_CLIPPERS
// Compute bounding box of region/file intersection expressed in grid
// units
temp_geom = GEOSEnvelope(region_in_file_geom);
temp_ring = GEOSGetExteriorRing(temp_geom);
npoints = GEOSGeomGetNumPoints(temp_ring);
for (p=0 ; plevels[iz]->resolution;
mapcache_grid_get_xy(&ctx, grid, region_in_file_bbox.maxx-res,
region_in_file_bbox.maxy-res, iz, &(til_region_in_file_bbox.maxx),
&(til_region_in_file_bbox.maxy));
if (til_region_in_file_bbox.minx > til_region_in_file_bbox.maxx) {
int swap = til_region_in_file_bbox.maxx;
til_region_in_file_bbox.maxx = til_region_in_file_bbox.minx;
til_region_in_file_bbox.minx = swap;
}
if (til_region_in_file_bbox.miny > til_region_in_file_bbox.maxy) {
int swap = til_region_in_file_bbox.maxy;
til_region_in_file_bbox.maxy = til_region_in_file_bbox.miny;
til_region_in_file_bbox.miny = swap;
}
if ((cache->xcount > 0) && (cache->ycount > 0)) {
if (til_region_in_file_bbox.maxx>(til_file_bbox.minx+cache->xcount-1))
{
(til_region_in_file_bbox.maxx)--;
}
if (til_region_in_file_bbox.maxy>(til_file_bbox.miny+cache->ycount-1))
{
(til_region_in_file_bbox.maxy)--;
}
}
// If region/file intersection is a rectangle, count tiles in a single
// step
if (region_in_file_is_rectangle) {
int tmpmax, tmpcached;
count_tiles_in_rectangle(
&ctx,
iz,
til_region_in_file_bbox,
tileset,
grid_link,
dimensions,
file_name,
count_query,
&tmpmax,
&tmpcached
);
tiles_max_in_file += tmpmax;
tiles_cached_in_file += tmpcached;
}
#ifdef USE_CLIPPERS
// Else, if file is partially inside region, iterate over tiles
else {
int tmpmax, tmpcached;
count_tiles_in_region(
&ctx,
iz,
til_region_in_file_bbox,
tileset,
grid_link,
dimensions,
region_prepgeom,
(file_open_report==APR_SUCCESS),
&tmpmax,
&tmpcached
);
tiles_max_in_file += tmpmax;
tiles_cached_in_file += tmpcached;
}
#endif // USE_CLIPPERS
// Report identification and coverage information for a single DB file
// for current zoom level and extent
if (json_output) {
if (report_missing_files || (file_open_report == APR_SUCCESS)) {
jfile = cJSON_CreateObject();
cJSON_AddItemToObject(jfiles, "", jfile);
cJSON_AddStringToObject(jfile, "file_name", file_name);
cJSON_AddNumberToObject(jfile, "file_size", fileinfo.size);
jitem = cJSON_AddArrayToObject(jfile, "file_bounding_box");
cJSON_AddNumberToObject(jitem, "", file_bbox.minx);
cJSON_AddNumberToObject(jitem, "", file_bbox.miny);
cJSON_AddNumberToObject(jitem, "", file_bbox.maxx);
cJSON_AddNumberToObject(jitem, "", file_bbox.maxy);
jregion = cJSON_CreateObject();
cJSON_AddItemToObject(jfile, "region_in_file", jregion);
jitem = cJSON_AddArrayToObject(jregion, "bounding_box");
cJSON_AddNumberToObject(jitem, "", region_in_file_bbox.minx);
cJSON_AddNumberToObject(jitem, "", region_in_file_bbox.miny);
cJSON_AddNumberToObject(jitem, "", region_in_file_bbox.maxx);
cJSON_AddNumberToObject(jitem, "", region_in_file_bbox.maxy);
#ifdef USE_CLIPPERS
jitem = GEOSGeometry_to_cJSON(region_in_file_geom);
#else // use _bbox instead of _geom
jitem = mapcache_extent_to_cJSON(®ion_in_file_bbox);
#endif // USE_CLIPPERS
cJSON_AddItemToObject(jregion, "geometry", jitem);
jitem = cJSON_CreateObject();
cJSON_AddItemToObject(jfile, "nb_tiles_in_region", jitem);
cJSON_AddNumberToObject(jitem,"missing_in_file",
tiles_max_in_file - tiles_cached_in_file);
cJSON_AddNumberToObject(jitem,"cached_in_file",
tiles_cached_in_file);
cJSON_AddNumberToObject(jitem,"max_in_file", tiles_max_in_file);
cJSON_AddNumberToObject(jitem,"coverage",
(double)tiles_cached_in_file/(double)tiles_max_in_file);
}
}
// Add tiles in file to tiles in zoom level
tiles_max_in_level += tiles_max_in_file;
tiles_cached_in_level += tiles_cached_in_file;
// Release resources that are no longer needed
#ifdef USE_CLIPPERS
GEOSGeom_destroy(file_geom);
GEOSGeom_destroy(region_in_file_geom);
#endif // USE_CLIPPERS
}
}
// Add tiles in level to tiles in cache
tiles_max_in_cache += tiles_max_in_level;
tiles_cached_in_cache += tiles_cached_in_level;
// Report coverage information for current zoom level and extent
if (json_output) {
jitem = cJSON_CreateObject();
cJSON_AddItemToObject(jzoom, "nb_tiles_in_region", jitem);
cJSON_AddNumberToObject(jitem, "missing_in_level",
tiles_max_in_level - tiles_cached_in_level);
cJSON_AddNumberToObject(jitem, "cached_in_level", tiles_cached_in_level);
cJSON_AddNumberToObject(jitem, "max_in_level", tiles_max_in_level);
cJSON_AddNumberToObject(jitem,"coverage",
(double)tiles_cached_in_level/(double)tiles_max_in_level);
}
}
// Report global coverage information
if (json_output) {
jitem = cJSON_CreateObject();
cJSON_AddItemToObject(jreport, "nb_tiles_in_region", jitem);
cJSON_AddNumberToObject(jitem, "missing_in_cache",
tiles_max_in_cache - tiles_cached_in_cache);
cJSON_AddNumberToObject(jitem, "cached_in_cache", tiles_cached_in_cache);
cJSON_AddNumberToObject(jitem, "max_in_cache", tiles_max_in_cache);
cJSON_AddNumberToObject(jitem,"coverage",
(double)tiles_cached_in_cache/(double)tiles_max_in_cache);
jitem = cJSON_CreateObject();
cJSON_AddItemToObject(jreport, "sizes", jitem);
cJSON_AddNumberToObject(jitem, "total_size_of_files", size_of_cache);
cJSON_AddNumberToObject(jitem, "total_nbtiles_in_files", tiles_in_cache);
if (tiles_in_cache > 0) {
apr_off_t average_tile_size = size_of_cache/tiles_in_cache;
cJSON_AddNumberToObject(jitem, "average_tile_size", average_tile_size);
cJSON_AddNumberToObject(jitem, "estimated_max_cache_size",
average_tile_size*tiles_max_in_cache);
cJSON_AddNumberToObject(jitem, "estimated_cached_cache_size",
average_tile_size*tiles_cached_in_cache);
cJSON_AddNumberToObject(jitem, "estimated_missing_cache_size",
average_tile_size*(tiles_max_in_cache-tiles_cached_in_cache));
} else {
const char * na = "N/A: cache is empty";
cJSON_AddStringToObject(jitem, "average_tile_size", na);
cJSON_AddStringToObject(jitem, "estimated_max_cache_size", na);
cJSON_AddNumberToObject(jitem, "estimated_cached_cache_size", 0);
cJSON_AddStringToObject(jitem, "estimated_missing_cache_size", na);
}
if (!report_missing_files) {
cJSON_AddNumberToObject(jreport, "nb_missing_files", nb_missing_files);
}
}
// Last progression indication
if (show_progress) {
fprintf(stderr, "\033[2K Finished: 100.000%% done\n");
}
// Display JSON report
if (json_output) {
printf("%s\n", cJSON_Print(jreport));
}
success:
_destroy_json_pool();
#ifdef USE_CLIPPERS
finishGEOS();
#endif // USE_CLIPPERS
apr_terminate();
return 0;
failure:
if (GC_HAS_ERROR(&ctx)) {
fprintf(stderr, "%s: %s\n", base_name(argv[0]),
ctx.get_error_message(&ctx));
}
_destroy_json_pool();
#ifdef USE_CLIPPERS
finishGEOS();
#endif // USE_CLIPPERS
apr_terminate();
return 1;
}
// vim: set tw=79 ts=2 sw=2 sts=2 et ai si nonu syn=c fo+=ro :
mapcache-rel-1-14-1/contrib/mapcache_detail/mapcache_detail_config.h.in 0000664 0000000 0000000 00000000174 14653160677 0026047 0 ustar 00root root 0000000 0000000 #ifndef _MAPCACHE_DETAIL_CONFIG_H
#define _MAPCACHE_DETAIL_CONFIG_H
#cmakedefine USE_OGR 1
#cmakedefine USE_GEOS 1
#endif
mapcache-rel-1-14-1/include/ 0000775 0000000 0000000 00000000000 14653160677 0015557 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/include/cJSON.h 0000664 0000000 0000000 00000034346 14653160677 0016656 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 3
#include
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check if the item is a string and return its valuestring */
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/arrray that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif
mapcache-rel-1-14-1/include/errors.h 0000664 0000000 0000000 00000003634 14653160677 0017252 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#ifndef MAPCACHE_ERRORS_H_
#define MAPCACHE_ERRORS_H_
typedef enum {
MAPCACHE_DEBUG,
MAPCACHE_INFO,
MAPCACHE_NOTICE,
MAPCACHE_WARN,
MAPCACHE_ERROR,
MAPCACHE_CRIT,
MAPCACHE_ALERT,
MAPCACHE_EMERG
} mapcache_log_level;
typedef enum {
MAPCACHE_REPORT_LOG,
MAPCACHE_REPORT_MSG,
MAPCACHE_REPORT_ERROR_IMG,
MAPCACHE_REPORT_EMPTY_IMG,
MAPCACHE_REPORT_CUSTOM_IMG
} mapcache_error_reporting;
#endif /* ERRORS_H_ */
/* vim: ts=2 sts=2 et sw=2
*/
mapcache-rel-1-14-1/include/ezxml.h 0000664 0000000 0000000 00000015732 14653160677 0017077 0 ustar 00root root 0000000 0000000 /* ezxml.h
*
* Copyright 2004-2006 Aaron Voisine
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _EZXML_H
#define _EZXML_H
#include
#include
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
# define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
#define EZXML_BUFSIZE 1024 // size of internal memory buffers
#define EZXML_NAMEM 0x80 // name is malloced
#define EZXML_TXTM 0x40 // txt is malloced
#define EZXML_DUP 0x20 // attribute name and value are strduped
typedef struct ezxml *ezxml_t;
struct ezxml {
char *name; // tag name
char **attr; // tag attributes { name, value, name, value, ... NULL }
char *txt; // tag character content, empty string if none
size_t off; // tag offset from start of parent tag character content
ezxml_t next; // next tag with same name in this section at this depth
ezxml_t sibling; // next tag with different name in same section and depth
ezxml_t ordered; // next tag, same section and depth, in original order
ezxml_t child; // head of sub tag list, NULL if none
ezxml_t parent; // parent tag, NULL if current tag is root tag
short flags; // additional information
};
// Given a string of xml data and its length, parses it and creates an ezxml
// structure. For efficiency, modifies the data by adding null terminators
// and decoding ampersand sequences. If you don't want this, copy the data and
// pass in the copy. Returns NULL on failure.
DLL_EXPORT ezxml_t ezxml_parse_str(char *s, size_t len);
// A wrapper for ezxml_parse_str() that accepts a file descriptor. First
// attempts to mem map the file. Failing that, reads the file into memory.
// Returns NULL on failure.
DLL_EXPORT ezxml_t ezxml_parse_fd(int fd);
// a wrapper for ezxml_parse_fd() that accepts a file name
DLL_EXPORT ezxml_t ezxml_parse_file(const char *file);
// Wrapper for ezxml_parse_str() that accepts a file stream. Reads the entire
// stream into memory and then parses it. For xml files, use ezxml_parse_file()
// or ezxml_parse_fd()
DLL_EXPORT ezxml_t ezxml_parse_fp(FILE *fp);
// returns the first child tag (one level deeper) with the given name or NULL
// if not found
DLL_EXPORT ezxml_t ezxml_child(ezxml_t xml, const char *name);
// returns the next tag of the same name in the same section and depth or NULL
// if not found
#define ezxml_next(xml) ((xml) ? xml->next : NULL)
// Returns the Nth tag with the same name in the same section at the same depth
// or NULL if not found. An index of 0 returns the tag given.
DLL_EXPORT ezxml_t ezxml_idx(ezxml_t xml, int idx);
// returns the name of the given tag
#define ezxml_name(xml) ((xml) ? xml->name : NULL)
// returns the given tag's character content or empty string if none
#define ezxml_txt(xml) ((xml) ? xml->txt : "")
// returns the value of the requested tag attribute, or NULL if not found
DLL_EXPORT const char *ezxml_attr(ezxml_t xml, const char *attr);
// Traverses the ezxml structure to retrieve a specific subtag. Takes a
// variable length list of tag names and indexes. The argument list must be
// terminated by either an index of -1 or an empty string tag name. Example:
// title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1);
// This retrieves the title of the 3rd book on the 1st shelf of library.
// Returns NULL if not found.
DLL_EXPORT ezxml_t ezxml_get(ezxml_t xml, ...);
// Converts an ezxml structure back to xml. Returns a string of xml data that
// must be freed.
DLL_EXPORT char *ezxml_toxml(ezxml_t xml);
// returns a NULL terminated array of processing instructions for the given
// target
DLL_EXPORT const char **ezxml_pi(ezxml_t xml, const char *target);
// frees the memory allocated for an ezxml structure
DLL_EXPORT void ezxml_free(ezxml_t xml);
// returns parser error message or empty string if none
DLL_EXPORT const char *ezxml_error(ezxml_t xml);
// returns a new empty ezxml structure with the given root tag name
DLL_EXPORT ezxml_t ezxml_new(const char *name);
// wrapper for ezxml_new() that strdup()s name
#define ezxml_new_d(name) ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM)
// Adds a child tag. off is the offset of the child tag relative to the start
// of the parent tag's character content. Returns the child tag.
DLL_EXPORT ezxml_t ezxml_add_child(ezxml_t xml, const char *name, size_t off);
// wrapper for ezxml_add_child() that strdup()s name
#define ezxml_add_child_d(xml, name, off) \
ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM)
// sets the character content for the given tag and returns the tag
DLL_EXPORT ezxml_t ezxml_set_txt(ezxml_t xml, const char *txt);
// wrapper for ezxml_set_txt() that strdup()s txt
#define ezxml_set_txt_d(xml, txt) \
ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM)
// Sets the given tag attribute or adds a new attribute if not found. A value
// of NULL will remove the specified attribute. Returns the tag given.
DLL_EXPORT ezxml_t ezxml_set_attr(ezxml_t xml, const char *name, const char *value);
// Wrapper for ezxml_set_attr() that strdup()s name/value. Value cannot be NULL
#define ezxml_set_attr_d(xml, name, value) \
ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value))
// sets a flag for the given tag and returns the tag
DLL_EXPORT ezxml_t ezxml_set_flag(ezxml_t xml, short flag);
// removes a tag along with its subtags without freeing its memory
DLL_EXPORT ezxml_t ezxml_cut(ezxml_t xml);
// inserts an existing tag into an ezxml structure
DLL_EXPORT ezxml_t ezxml_insert(ezxml_t xml, ezxml_t dest, size_t off);
// Moves an existing tag to become a subtag of dest at the given offset from
// the start of dest's character content. Returns the moved tag.
#define ezxml_move(xml, dest, off) ezxml_insert(ezxml_cut(xml), dest, off)
// removes a tag along with all its subtags
#define ezxml_remove(xml) ezxml_free(ezxml_cut(xml))
#ifdef __cplusplus
}
#endif
#endif // _EZXML_H
mapcache-rel-1-14-1/include/mapcache-config.h.in 0000664 0000000 0000000 00000001124 14653160677 0021337 0 ustar 00root root 0000000 0000000 #ifndef _MAPCACHE_CONFIG_H
#define _MAPCACHE_CONFIG_H
#cmakedefine USE_PIXMAN 1
#cmakedefine USE_FASTCGI 1
#cmakedefine USE_SQLITE 1
#cmakedefine USE_POSTGRESQL 1
#cmakedefine USE_BDB 1
#cmakedefine USE_LMDB 1
#cmakedefine USE_MEMCACHE 1
#cmakedefine USE_REDIS 1
#cmakedefine USE_TIFF 1
#cmakedefine USE_TIFF_WRITE 1
#cmakedefine USE_GEOTIFF 1
#cmakedefine USE_PCRE 1
#cmakedefine USE_PCRE2 1
#cmakedefine USE_MAPSERVER 1
#cmakedefine USE_RIAK 1
#cmakedefine USE_GDAL 1
#cmakedefine HAVE_STRNCASECMP 1
#cmakedefine HAVE_SYMLINK 1
#cmakedefine HAVE_STRPTIME 1
#cmakedefine HAVE_TIMEGM 1
#endif
mapcache-rel-1-14-1/include/mapcache-version.h.in 0000664 0000000 0000000 00000000526 14653160677 0021564 0 ustar 00root root 0000000 0000000 #ifndef _MAPCACHE_VERSION_H
#define _MAPCACHE_VERSION_H
#define MAPCACHE_VERSION_MAJOR @MAPCACHE_VERSION_MAJOR@
#define MAPCACHE_VERSION_MINOR @MAPCACHE_VERSION_MINOR@
#define MAPCACHE_VERSION_REV @MAPCACHE_VERSION_REVISION@
#define MAPCACHE_VERSION "@MAPCACHE_VERSION_STRING@"
#define MAPCACHE_VERSION_NUM @MAPCACHE_VERSION_NUM@
#endif
mapcache-rel-1-14-1/include/mapcache.h 0000664 0000000 0000000 00000162742 14653160677 0017505 0 ustar 00root root 0000000 0000000 /******************************************************************************
*
* Project: MapCache
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
/*! \file mapcache.h
\brief global function and structure declarations
*/
#ifndef MAPCACHE_H_
#define MAPCACHE_H_
#include "mapcache-config.h"
#include "mapcache-version.h"
#include
#include
#include
#include "util.h"
#include "ezxml.h"
#include "errors.h"
#include
#include
#include
#define MAPCACHE_SUCCESS 0
#define MAPCACHE_FAILURE 1
#define MAPCACHE_TRUE 1
#define MAPCACHE_FALSE 0
#define MAPCACHE_TILESET_WRONG_SIZE 2
#define MAPCACHE_TILESET_WRONG_RESOLUTION 3
#define MAPCACHE_TILESET_WRONG_EXTENT 4
#define MAPCACHE_CACHE_MISS 5
#define MAPCACHE_FILE_LOCKED 6
#define MAPCACHE_CACHE_RELOAD 7
#define MAPCACHE_MAX_NUM_TILES 1000
#define MAPCACHE_USERAGENT "mod-mapcache/"MAPCACHE_VERSION
#if defined(_WIN32) && !defined(__CYGWIN__)
# define MS_DLL_EXPORT __declspec(dllexport)
#else
#define MS_DLL_EXPORT
#endif
typedef struct mapcache_image_format mapcache_image_format;
typedef struct mapcache_image_format_mixed mapcache_image_format_mixed;
typedef struct mapcache_image_format_png mapcache_image_format_png;
typedef struct mapcache_image_format_png_q mapcache_image_format_png_q;
typedef struct mapcache_image_format_jpeg mapcache_image_format_jpeg;
typedef struct mapcache_image_format_raw mapcache_image_format_raw;
typedef struct mapcache_cfg mapcache_cfg;
typedef struct mapcache_tileset mapcache_tileset;
typedef struct mapcache_cache mapcache_cache;
typedef struct mapcache_source mapcache_source;
typedef struct mapcache_buffer mapcache_buffer;
typedef struct mapcache_tile mapcache_tile;
typedef struct mapcache_metatile mapcache_metatile;
typedef struct mapcache_feature_info mapcache_feature_info;
typedef struct mapcache_request_get_feature_info mapcache_request_get_feature_info;
typedef struct mapcache_map mapcache_map;
typedef struct mapcache_http_response mapcache_http_response;
typedef struct mapcache_http mapcache_http;
typedef struct mapcache_request mapcache_request;
typedef struct mapcache_request_image mapcache_request_image;
typedef struct mapcache_request_proxy mapcache_request_proxy;
typedef struct mapcache_request_get_capabilities mapcache_request_get_capabilities;
typedef struct mapcache_forwarding_rule mapcache_forwarding_rule;
typedef struct mapcache_request_get_tile mapcache_request_get_tile;
typedef struct mapcache_request_get_map mapcache_request_get_map;
typedef struct mapcache_service mapcache_service;
typedef struct mapcache_server_cfg mapcache_server_cfg;
typedef struct mapcache_image mapcache_image;
typedef struct mapcache_grid mapcache_grid;
typedef struct mapcache_grid_level mapcache_grid_level;
typedef struct mapcache_grid_link mapcache_grid_link;
typedef struct mapcache_rule mapcache_rule;
typedef struct mapcache_ruleset mapcache_ruleset;
typedef struct mapcache_context mapcache_context;
typedef struct mapcache_dimension mapcache_dimension;
typedef struct mapcache_requested_dimension mapcache_requested_dimension;
typedef struct mapcache_extent mapcache_extent;
typedef struct mapcache_extent_i mapcache_extent_i;
typedef struct mapcache_connection_pool mapcache_connection_pool;
typedef struct mapcache_locker mapcache_locker;
typedef enum {
MAPCACHE_DIMENSION_VALUES,
MAPCACHE_DIMENSION_REGEX,
MAPCACHE_DIMENSION_POSTGRESQL,
MAPCACHE_DIMENSION_SQLITE,
MAPCACHE_DIMENSION_ELASTICSEARCH
} mapcache_dimension_type;
typedef enum {
MAPCACHE_DIMENSION_ASSEMBLY_NONE,
MAPCACHE_DIMENSION_ASSEMBLY_STACK,
MAPCACHE_DIMENSION_ASSEMBLY_ANIMATE
} mapcache_dimension_assembly_type;
/** \defgroup utility Utility */
/** @{ */
struct mapcache_extent {
double minx;
double miny;
double maxx;
double maxy;
};
struct mapcache_extent_i {
int minx;
int miny;
int maxx;
int maxy;
};
#ifdef __GNUC__
/** Tag a function to have printf() formatting */
#define MAPCACHE_PRINT_FUNC_FORMAT(format_idx, arg_idx) \
__attribute__((__format__(__printf__, format_idx, arg_idx)))
#else
#define MAPCACHE_PRINT_FUNC_FORMAT(format_idx, arg_idx)
#endif
mapcache_image *mapcache_error_image(mapcache_context *ctx, int width, int height, char *msg);
/**
* \interface mapcache_context
* \brief structure passed to most mapcache functions to abstract common functions
*/
struct mapcache_context {
/**
* \brief indicate that an error has happened
* \memberof mapcache_context
* \param c
* \param code the error code
* \param message human readable message of what happened
*/
void (*set_error)(mapcache_context *ctx, int code, char *message, ...) MAPCACHE_PRINT_FUNC_FORMAT(3, 4);
void (*set_exception)(mapcache_context *ctx, char *key, char *message, ...) MAPCACHE_PRINT_FUNC_FORMAT(3, 4);
/**
* \brief query context to know if an error has occurred
* \memberof mapcache_context
*/
int (*get_error)(mapcache_context * ctx);
/**
* \brief get human readable message for the error
* \memberof mapcache_context
*/
char* (*get_error_message)(mapcache_context * ctx);
/**
* \brief get human readable message for the error
* \memberof mapcache_context
*/
void (*clear_errors)(mapcache_context * ctx);
/**
* \brief clear current error and store it in mapcache_error
* \memberof mapcache_context
*/
void (*pop_errors)(mapcache_context * ctx, void **error);
/**
* \brief restore error status from mapcache_error
* \memberof mapcache_context
*/
void (*push_errors)(mapcache_context * ctx, void *error);
/**
* \brief log a message
* \memberof mapcache_context
*/
void (*log)(mapcache_context *ctx, mapcache_log_level level, char *message, ...);
const char* (*get_instance_id)(mapcache_context * ctx);
mapcache_context* (*clone)(mapcache_context *ctx);
apr_pool_t *pool;
mapcache_connection_pool *connection_pool;
char *_contenttype;
char *_errmsg;
int _errcode;
mapcache_cfg *config;
mapcache_service *service;
apr_table_t *exceptions;
int supports_redirects;
apr_table_t *headers_in;
};
MS_DLL_EXPORT void mapcache_context_init(mapcache_context *ctx);
MS_DLL_EXPORT void mapcache_context_copy(mapcache_context *src, mapcache_context *dst);
#define GC_CHECK_ERROR_RETURN(ctx) if(((mapcache_context*)ctx)->_errcode) return MAPCACHE_FAILURE;
#define GC_CHECK_ERROR(ctx) if(((mapcache_context*)ctx)->_errcode) return;
#define GC_HAS_ERROR(ctx) (((mapcache_context*)ctx)->_errcode > 0)
/**
* \brief autoexpanding buffer that allocates memory from a pool
* \sa mapcache_buffer_create()
* \sa mapcache_buffer_append()
*
*/
struct mapcache_buffer {
void* buf; /**< pointer to the actual data contained in buffer */
size_t size; /**< number of bytes actually used in the buffer */
size_t avail; /**< number of bytes allocated */
apr_pool_t* pool; /**< apache pool to allocate from */
};
/* in buffer.c */
/**
* \brief create and initialize a mapcache_buffer
* \memberof mapcache_buffer
* \param initialStorage the initial size that should be allocated in the buffer.
* defaults to #INITIAL_BUFFER_SIZE.
* \param pool the pool from which to allocate memory.
*/
mapcache_buffer *mapcache_buffer_create(size_t initialStorage, apr_pool_t* pool);
/**
* \brief append data
* \memberof mapcache_buffer
* \param buffer
* \param len the lenght of the data to append.
* \param data the data to append
*/
int mapcache_buffer_append(mapcache_buffer *buffer, size_t len, void *data);
/** @} */
/** \defgroup source Sources */
/** @{ */
typedef enum {
MAPCACHE_SOURCE_WMS,
MAPCACHE_SOURCE_MAPSERVER,
MAPCACHE_SOURCE_DUMMY,
MAPCACHE_SOURCE_GDAL,
MAPCACHE_SOURCE_FALLBACK
} mapcache_source_type;
/**\interface mapcache_source
* \brief a source of data that can return image data
*/
struct mapcache_source {
char *name; /**< the key this source can be referenced by */
mapcache_extent data_extent; /**< extent in which this source can produce data */
mapcache_source_type type;
apr_table_t *metadata;
unsigned int retry_count;
double retry_delay;
apr_array_header_t *info_formats;
/**
* \brief get the data for the metatile
*
* sets the mapcache_metatile::tile::data for the given tile
*/
void (*_render_map)(mapcache_context *ctx, mapcache_source *psource, mapcache_map *map);
void (*_query_info)(mapcache_context *ctx, mapcache_source *psource, mapcache_feature_info *fi);
void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_source * source, mapcache_cfg *config);
void (*configuration_check)(mapcache_context *ctx, mapcache_cfg *cfg, mapcache_source * source);
};
mapcache_http* mapcache_http_configuration_parse_xml(mapcache_context *ctx,ezxml_t node);
mapcache_http* mapcache_http_clone(mapcache_context *ctx, mapcache_http *orig);
struct mapcache_http {
char *url; /**< the base url to request */
apr_table_t *headers; /**< additional headers to add to the http request, eg, Referer */
char *post_body;
size_t post_len;
int connection_timeout;
int timeout;
/* TODO: authentication */
};
/** \defgroup cache Caches */
/** @{ */
typedef enum {
MAPCACHE_CACHE_DISK
,MAPCACHE_CACHE_REST
,MAPCACHE_CACHE_MEMCACHE
,MAPCACHE_CACHE_SQLITE
,MAPCACHE_CACHE_BDB
,MAPCACHE_CACHE_TC
,MAPCACHE_CACHE_TIFF
,MAPCACHE_CACHE_COMPOSITE
,MAPCACHE_CACHE_COUCHBASE
,MAPCACHE_CACHE_RIAK
,MAPCACHE_CACHE_REDIS
,MAPCACHE_CACHE_LMDB
} mapcache_cache_type;
/** \interface mapcache_cache
* \brief a place to cache a mapcache_tile
*/
struct mapcache_cache {
char *name; /**< key this cache is referenced by */
mapcache_cache_type type;
apr_table_t *metadata;
unsigned int retry_count;
double retry_delay;
/**
* get tile content from cache
* \returns MAPCACHE_SUCCESS if the data was correctly loaded from the cache
* \returns MAPCACHE_FAILURE if the file exists but contains no data
* \returns MAPCACHE_CACHE_MISS if the file does not exist on the cache
* \memberof mapcache_cache
*/
int (*_tile_get)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
/**
* delete tile from cache
*
* \memberof mapcache_cache
*/
void (*_tile_delete)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
int (*_tile_exists)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
/**
* set tile content to cache
* \memberof mapcache_cache
*/
void (*_tile_set)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile * tile);
void (*_tile_multi_set)(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tiles, int ntiles);
void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_cache * cache, mapcache_cfg *config);
void (*configuration_post_config)(mapcache_context *ctx, mapcache_cache * cache, mapcache_cfg *config);
void (*child_init)(mapcache_context *ctx, mapcache_cache *cache, apr_pool_t *pchild);
};
MS_DLL_EXPORT int mapcache_cache_tile_get(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
void mapcache_cache_tile_delete(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
MS_DLL_EXPORT int mapcache_cache_tile_exists(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
MS_DLL_EXPORT void mapcache_cache_tile_set(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tile);
void mapcache_cache_tile_multi_set(mapcache_context *ctx, mapcache_cache *cache, mapcache_tile *tiles, int ntiles);
MS_DLL_EXPORT void mapcache_cache_child_init(mapcache_context *ctx, mapcache_cfg *config, apr_pool_t *pchild);
static inline void mapcache_cache_child_init_noop(mapcache_context *ctx, mapcache_cache *cache, apr_pool_t *pchild) {
};
/**
* \memberof mapcache_cache_sqlite
*/
mapcache_cache* mapcache_cache_sqlite_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_mbtiles_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_bdb
*/
mapcache_cache *mapcache_cache_bdb_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_lmdb
*/
mapcache_cache *mapcache_cache_lmdb_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_memcache
*/
mapcache_cache* mapcache_cache_memcache_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_couchbase
*/
mapcache_cache* mapcache_cache_couchbase_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_tc
*/
mapcache_cache* mapcache_cache_tc_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_riak
*/
mapcache_cache* mapcache_cache_riak_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_redis
*/
mapcache_cache* mapcache_cache_redis_create(mapcache_context* ctx);
/** @} */
typedef enum {
MAPCACHE_REQUEST_UNKNOWN,
MAPCACHE_REQUEST_GET_TILE,
MAPCACHE_REQUEST_GET_MAP,
MAPCACHE_REQUEST_GET_CAPABILITIES,
MAPCACHE_REQUEST_GET_FEATUREINFO,
MAPCACHE_REQUEST_PROXY
} mapcache_request_type;
typedef enum {
MAPCACHE_GETMAP_ERROR,
MAPCACHE_GETMAP_ASSEMBLE,
MAPCACHE_GETMAP_FORWARD
} mapcache_getmap_strategy;
typedef enum {
MAPCACHE_RESAMPLE_NEAREST,
MAPCACHE_RESAMPLE_BILINEAR
} mapcache_resample_mode;
/**
* \brief a request sent by a client
*/
struct mapcache_request {
mapcache_request_type type;
mapcache_service *service;
};
struct mapcache_request_image {
mapcache_request request;
mapcache_image_format *format;
};
struct mapcache_request_get_tile {
mapcache_request_image image_request;
/**
* a list of tiles requested by the client
*/
mapcache_tile **tiles;
/**
* the number of tiles requested by the client.
* If more than one, and merging is enabled,
* the supplied tiles will be merged together
* before being returned to the client
*/
int ntiles;
int allow_redirect;
};
struct mapcache_http_response {
mapcache_buffer *data;
apr_table_t *headers;
long code;
apr_time_t mtime;
};
struct mapcache_map {
mapcache_tileset *tileset;
mapcache_grid_link *grid_link;
apr_array_header_t *dimensions;
mapcache_buffer *encoded_data;
mapcache_image *raw_image;
int nodata; /**< \sa mapcache_tile::nodata */
int width, height;
mapcache_extent extent;
apr_time_t mtime; /**< last modification time */
int expires; /**< time in seconds after which the tile should be rechecked for validity */
};
struct mapcache_feature_info {
mapcache_map map;
int i,j;
char *format;
mapcache_buffer *data;
};
struct mapcache_request_get_feature_info {
mapcache_request request;
mapcache_feature_info *fi;
};
struct mapcache_request_get_map {
mapcache_request_image image_request;
mapcache_map **maps;
int nmaps;
mapcache_getmap_strategy getmap_strategy;
mapcache_resample_mode resample_mode;
};
struct mapcache_request_get_capabilities {
mapcache_request request;
/**
* the body of the capabilities
*/
char *capabilities;
/**
* the mime type
*/
char *mime_type;
};
struct mapcache_forwarding_rule {
char *name;
mapcache_http *http;
apr_array_header_t *match_params; /* actually those are mapcache_dimensions */
int append_pathinfo;
size_t max_post_len;
};
struct mapcache_request_proxy {
mapcache_request request;
mapcache_forwarding_rule *rule;
apr_table_t *params;
apr_table_t *headers;
const char *pathinfo;
char *post_buf;
size_t post_len;
};
/** \defgroup services Services*/
/** @{ */
#define MAPCACHE_SERVICES_COUNT 8
typedef enum {
MAPCACHE_SERVICE_TMS=0, MAPCACHE_SERVICE_WMTS,
MAPCACHE_SERVICE_DEMO, MAPCACHE_SERVICE_GMAPS, MAPCACHE_SERVICE_KML,
MAPCACHE_SERVICE_VE, MAPCACHE_SERVICE_MAPGUIDE, MAPCACHE_SERVICE_WMS
} mapcache_service_type;
#define MAPCACHE_UNITS_COUNT 3
typedef enum {
MAPCACHE_UNIT_METERS=0, MAPCACHE_UNIT_DEGREES, MAPCACHE_UNIT_FEET
} mapcache_unit;
/* defined in util.c*/
extern const double mapcache_meters_per_unit[MAPCACHE_UNITS_COUNT];
/** \interface mapcache_service
* \brief a standard service (eg WMS, TMS)
*/
struct mapcache_service {
char *name;
mapcache_service_type type;
/**
* the pathinfo prefix of the url that routes to this service
* eg, for accessing a wms service on http://host/mapcache/mywmsservice? ,
* url_prefix would take the value "mywmsservice"
*/
char *url_prefix;
/**
* \brief allocates and populates a mapcache_request corresponding to the parameters received
*/
void (*parse_request)(mapcache_context *ctx, mapcache_service *service, mapcache_request **request, const char *path_info, apr_table_t *params, mapcache_cfg * config);
/**
* \param request the received request (should be of type MAPCACHE_REQUEST_CAPABILITIES
* \param url the full url at which the service is available
*/
void (*create_capabilities_response)(mapcache_context *ctx, mapcache_request_get_capabilities *request, char *url, char *path_info, mapcache_cfg *config);
/**
* parse advanced configuration options for the selected service
*/
void (*configuration_parse_xml)(mapcache_context *ctx, ezxml_t xml, mapcache_service * service, mapcache_cfg *config);
void (*format_error)(mapcache_context *ctx, mapcache_service * service, char *err_msg,
char **err_body, apr_table_t *headers);
};
/**
* \brief create and initialize a mapcache_service_wms
* \memberof mapcache_service_wms
*/
mapcache_service* mapcache_service_wms_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_ve
* \memberof mapcache_service_ve
*/
mapcache_service* mapcache_service_ve_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_mapguide
* \memberof mapcache_service_mapguide
*/
mapcache_service* mapcache_service_mapguide_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_gmaps
* \memberof mapcache_service_gmaps
*/
mapcache_service* mapcache_service_gmaps_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_kml
* \memberof mapcache_service_kml
*/
mapcache_service* mapcache_service_kml_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_tms
* \memberof mapcache_service_tms
*/
mapcache_service* mapcache_service_tms_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_wmts
* \memberof mapcache_service_wtms
*/
mapcache_service* mapcache_service_wmts_create(mapcache_context *ctx);
/**
* \brief create and initialize a mapcache_service_demo
* \memberof mapcache_service_demo
*/
mapcache_service* mapcache_service_demo_create(mapcache_context *ctx);
/**
* \brief return the request that corresponds to the given url
*/
MS_DLL_EXPORT void mapcache_service_dispatch_request(mapcache_context *ctx,
mapcache_request **request,
char *pathinfo,
apr_table_t *params,
mapcache_cfg *config);
/**
* \brief return the number of enabled/configured services
*/
MS_DLL_EXPORT int mapcache_config_services_enabled(mapcache_context *ctx, mapcache_cfg *config);
/** @} */
/** \defgroup image Image Data Handling */
/** @{ */
typedef enum {
GC_UNKNOWN, GC_PNG, GC_JPEG, GC_RAW
} mapcache_image_format_type;
typedef enum {
MC_EMPTY_UNKNOWN, MC_EMPTY_YES, MC_EMPTY_NO
} mapcache_image_blank_type;
typedef enum {
MC_ALPHA_UNKNOWN, MC_ALPHA_YES, MC_ALPHA_NO
} mapcache_image_alpha_type;
/**\class mapcache_image
* \brief representation of an RGBA image
*
* to access a pixel at position x,y, you should use the #GET_IMG_PIXEL macro
*/
struct mapcache_image {
unsigned char *data; /**< pointer to the beginning of image data, stored in rgba order */
size_t w; /**< width of the image */
size_t h; /**< height of the image */
size_t stride; /**< stride of an image row */
mapcache_image_blank_type is_blank;
mapcache_image_alpha_type has_alpha;
};
/** \def GET_IMG_PIXEL
* return the address of a pixel
* \param y the row
* \param x the column
* \param img the mapcache_image
* \returns a pointer to the pixel
*/
#define GET_IMG_PIXEL(img,x,y) (&((img).data[(y)*(img).stride + (x)*4]))
/**
* \brief initialize a new mapcache_image
*/
mapcache_image* mapcache_image_create(mapcache_context *ctx);
mapcache_image* mapcache_image_create_with_data(mapcache_context *ctx, int width, int height);
void mapcache_image_copy_resampled_nearest(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
double off_x, double off_y, double scale_x, double scale_y);
void mapcache_image_copy_resampled_bilinear(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
double off_x, double off_y, double scale_x, double scale_y, int reflect_edges);
/**
* \brief merge two images
* \param base the imae to merge onto
* \param overlay the image to overlay onto
* \param ctx the context
* when finished, base will be modified and have overlay merged onto it
*/
void mapcache_image_merge(mapcache_context *ctx, mapcache_image *base, mapcache_image *overlay);
void mapcache_image_copy_resampled(mapcache_context *ctx, mapcache_image *src, mapcache_image *dst,
int srcX, int srcY, int srcW, int srcH,
int dstX, int dstY, int dstW, int dstH);
/**
* \brief split the given metatile into tiles
* \param mt the metatile to split
* \param r the context
*/
void mapcache_image_metatile_split(mapcache_context *ctx, mapcache_metatile *mt);
/**
* \brief check if given image is composed of a unique color
* \param image the mapcache_image to process
* \returns MAPCACHE_TRUE if the image contains a single color
* \returns MAPCACHE_FALSE if the image has more than one color
*/
int mapcache_image_blank_color(mapcache_image* image);
/**
* \brief check if image has some non opaque pixels
*/
int mapcache_image_has_alpha(mapcache_image *img, unsigned int cutoff);
void mapcache_image_fill(mapcache_context *ctx, mapcache_image *image, const unsigned char *fill_color);
/** @} */
/** \defgroup http HTTP Request handling*/
/** @{ */
void mapcache_http_do_request(mapcache_context *ctx, mapcache_http *req, mapcache_buffer *data, apr_table_t *headers, long *http_code);
char* mapcache_http_build_url(mapcache_context *ctx, char *base, apr_table_t *params);
MS_DLL_EXPORT apr_table_t *mapcache_http_parse_param_string(mapcache_context *ctx, char *args);
/** @} */
/** \defgroup configuration Configuration*/
/** @{ */
typedef enum {
MAPCACHE_MODE_NORMAL,
MAPCACHE_MODE_MIRROR_COMBINED,
MAPCACHE_MODE_MIRROR_SPLIT
} mapcache_mode;
typedef enum {
MAPCACHE_LOCKER_DISK,
MAPCACHE_LOCKER_MEMCACHE,
MAPCACHE_LOCKER_FALLBACK
} mapcache_lock_mode;
typedef enum {
MAPCACHE_LOCK_AQUIRED,
MAPCACHE_LOCK_LOCKED,
MAPCACHE_LOCK_NOENT
} mapcache_lock_result;
struct mapcache_locker{
mapcache_lock_result (*aquire_lock)(mapcache_context *ctx, mapcache_locker *self, char *resource, void **lock);
mapcache_lock_result (*ping_lock)(mapcache_context *ctx, mapcache_locker *self, void *lock);
void (*release_lock)(mapcache_context *ctx, mapcache_locker *self, void *lock);
void (*parse_xml)(mapcache_context *ctx, mapcache_locker *self, ezxml_t node);
mapcache_lock_mode type;
double timeout;
double retry_interval; /* time to wait before checking again on a lock, in seconds */
};
mapcache_locker* mapcache_locker_disk_create(mapcache_context *ctx);
mapcache_locker* mapcache_locker_memcache_create(mapcache_context *ctx);
mapcache_locker* mapcache_locker_fallback_create(mapcache_context *ctx);
void mapcache_config_parse_locker(mapcache_context *ctx, ezxml_t node, mapcache_locker **locker);
void mapcache_config_parse_locker_old(mapcache_context *ctx, ezxml_t doc, mapcache_cfg *config);
/**
* a configuration that will be served
*/
struct mapcache_cfg {
/**
* a list of services that will be responded to
*/
mapcache_service * services[MAPCACHE_SERVICES_COUNT];
/**
* hashtable containing configured mapcache_source%s
*/
apr_hash_t *sources;
/**
* hashtable containing configured mapcache_cache%s
*/
apr_hash_t *caches;
/**
* hashtable containing configured mapcache_tileset%s
*/
apr_hash_t *tilesets;
/**
* hashtable containing configured mapcache_image_format%s
*/
apr_hash_t *image_formats;
/**
* hashtable containing (pre)defined grids
*/
apr_hash_t *grids;
/**
* hashtable containing (pre)defined rulesets
*/
apr_hash_t *rulesets;
/**
* the format to use for some miscelaneaous operations:
* - creating an empty image
* - creating an error image
* - as a fallback when merging multiple tiles
*/
mapcache_image_format *default_image_format;
/**
* how should error messages be reported to the user
*/
mapcache_error_reporting reporting;
/**
* encoded empty (tranpsarent) image that will be returned to clients if cofigured
* to return blank images upon error
*/
mapcache_buffer *empty_image;
apr_table_t *metadata;
mapcache_locker *locker;
int threaded_fetching;
/* for fastcgi only */
int autoreload; /* should the modification time of the config file be recorded
and the file be reparsed if it is modified. */
mapcache_log_level loglevel; /* logging verbosity. Ignored for the apache module
as in that case the apache LogLevel directive is
used. */
mapcache_mode mode;
/* return 404 on potentially blocking operations (proxying, source getmaps,
locks on metatile waiting, ... Used for nginx module */
int non_blocking;
// Parameters for connection_pool:
// - cp_hmax defines the maximum number of open connections at the same time
// - cp_ttl defines the maximum amount of time in microseconds an unused connection is valid
int cp_hmax;
int cp_ttl;
};
/**
*
* @param filename
* @param config
* @param pool
* @return
*/
MS_DLL_EXPORT void mapcache_configuration_parse(mapcache_context *ctx, const char *filename, mapcache_cfg *config, int cgi);
MS_DLL_EXPORT void mapcache_configuration_post_config(mapcache_context *ctx, mapcache_cfg *config);
void mapcache_configuration_parse_xml(mapcache_context *ctx, const char *filename, mapcache_cfg *config);
MS_DLL_EXPORT mapcache_cfg* mapcache_configuration_create(apr_pool_t *pool);
mapcache_source* mapcache_configuration_get_source(mapcache_cfg *config, const char *key);
MS_DLL_EXPORT mapcache_cache* mapcache_configuration_get_cache(mapcache_cfg *config, const char *key);
mapcache_grid *mapcache_configuration_get_grid(mapcache_cfg *config, const char *key);
MS_DLL_EXPORT mapcache_tileset* mapcache_configuration_get_tileset(mapcache_cfg *config, const char *key);
mapcache_image_format *mapcache_configuration_get_image_format(mapcache_cfg *config, const char *key);
mapcache_ruleset *mapcache_configuration_get_ruleset(mapcache_cfg *config, const char *key);
void mapcache_configuration_add_image_format(mapcache_cfg *config, mapcache_image_format *format, const char * key);
void mapcache_configuration_add_source(mapcache_cfg *config, mapcache_source *source, const char * key);
void mapcache_configuration_add_grid(mapcache_cfg *config, mapcache_grid *grid, const char * key);
void mapcache_configuration_add_ruleset(mapcache_cfg *config, mapcache_ruleset *ruleset, const char * key);
void mapcache_configuration_add_tileset(mapcache_cfg *config, mapcache_tileset *tileset, const char * key);
void mapcache_configuration_add_cache(mapcache_cfg *config, mapcache_cache *cache, const char * key);
/** @} */
/**
* \memberof mapcache_source
*/
void mapcache_source_init(mapcache_context *ctx, mapcache_source *source);
/**
* \memberof mapcache_source
*/
void mapcache_source_render_map(mapcache_context *ctx, mapcache_source *source, mapcache_map *map);
void mapcache_source_query_info(mapcache_context *ctx, mapcache_source *source,
mapcache_feature_info *fi);
/**
* \memberof mapcache_source_gdal
*/
mapcache_source* mapcache_source_gdal_create(mapcache_context *ctx);
/**
* \memberof mapcache_source_fallback
*/
mapcache_source* mapcache_source_fallback_create(mapcache_context *ctx);
/**
* \memberof mapcache_source_wms
*/
mapcache_source* mapcache_source_wms_create(mapcache_context *ctx);
/**
* \memberof mapcache_source_wms
*/
mapcache_source* mapcache_source_mapserver_create(mapcache_context *ctx);
mapcache_source* mapcache_source_dummy_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_disk
*/
mapcache_cache* mapcache_cache_disk_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_rest
*/
mapcache_cache* mapcache_cache_rest_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_s3_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_azure_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_google_create(mapcache_context *ctx);
/**
* \memberof mapcache_cache_tiff
*/
mapcache_cache* mapcache_cache_tiff_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_composite_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_fallback_create(mapcache_context *ctx);
mapcache_cache* mapcache_cache_multitier_create(mapcache_context *ctx);
/** \defgroup tileset Tilesets*/
/** @{ */
/**
* \brief Tile
* \sa mapcache_metatile
* \sa mapcache_tileset::metasize_x mapcache_tileset::metasize_x mapcache_tileset::metabuffer
*/
struct mapcache_tile {
mapcache_tileset *tileset; /**< the mapcache_tileset that corresponds to the tile*/
mapcache_grid_link *grid_link;
int x; /**< tile x index */
int y; /**< tile y index */
int z; /**< tile z index (zoom level) */
/**
* encoded image data for the tile.
* \sa mapcache_cache::tile_get()
* \sa mapcache_source::render_map()
* \sa mapcache_image_format
*/
mapcache_buffer *encoded_data;
char *redirect;
int allow_redirect;
mapcache_image *raw_image;
apr_time_t mtime; /**< last modification time */
int expires; /**< time in seconds after which the tile should be rechecked for validity */
apr_array_header_t *dimensions;
/**
* flag stating the tile is empty (i.e. fully transparent).
* if set, this indicates that there was no error per se, but that there was
* no way to get data back from the cache for this tile. This will happen for
* a tileset with no configured, for tiles that have not been preseeded.
* Tile assembling functions should look for this flag and ignore such a tile when
* compositing image data
*/
int nodata;
};
/**
* \brief MetaTile
* \extends mapcache_tile
*/
struct mapcache_metatile {
mapcache_map map;
int x,y,z;
int metasize_x, metasize_y;
int ntiles; /**< the number of mapcache_metatile::tiles contained in this metatile */
mapcache_tile *tiles; /**< the list of mapcache_tile s contained in this metatile */
};
struct mapcache_grid_level {
double resolution;
unsigned int maxx, maxy;
};
/**
* \brief mapcache_grid_origin
* determines at which extent extrema the tiles will originate from. Only
* BOTTOM_LEFT and TOP_LEFT are implemented
*/
typedef enum {
MAPCACHE_GRID_ORIGIN_BOTTOM_LEFT,
MAPCACHE_GRID_ORIGIN_TOP_LEFT,
MAPCACHE_GRID_ORIGIN_BOTTOM_RIGHT,
MAPCACHE_GRID_ORIGIN_TOP_RIGHT
} mapcache_grid_origin;
struct mapcache_grid {
char *name;
int nlevels;
char *srs;
apr_array_header_t *srs_aliases;
mapcache_extent extent;
mapcache_unit unit;
int tile_sx, tile_sy; /**= alpha_cutoff will be considered fully opaque */
};
mapcache_buffer* mapcache_empty_png_decode(mapcache_context *ctx, int width, int height, const unsigned char *hex_color, int *is_empty);
mapcache_image_format* mapcache_imageio_create_mixed_format(apr_pool_t *pool,
char *name, mapcache_image_format *transparent, mapcache_image_format *opaque, unsigned int alpha_cutoff);
struct mapcache_image_format_raw {
mapcache_image_format format;
};
mapcache_image_format* mapcache_imageio_create_raw_format(apr_pool_t *pool, char *name, char *extension, char *mime_type);
int mapcache_imageio_is_raw_tileset(mapcache_tileset *tileset);
/**\class mapcache_image_format_png_q
* \brief Quantized PNG format
* \extends mapcache_image_format_png
*/
struct mapcache_image_format_png_q {
mapcache_image_format_png format;
int ncolors; /**< number of colors used in quantization, 2-256 */
};
/**
* @param r
* @param buffer
* @return
*/
mapcache_image* _mapcache_imageio_png_decode(mapcache_context *ctx, mapcache_buffer *buffer);
void mapcache_image_create_empty(mapcache_context *ctx, mapcache_cfg *cfg);
/**
* @param r
* @param buffer
* @return
*/
void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer,
mapcache_image *image);
/**
* \brief create a format capable of creating RGBA png
* \memberof mapcache_image_format_png
* @param pool
* @param name
* @param compression the ZLIB compression to apply
* @return
*/
mapcache_image_format* mapcache_imageio_create_png_format(apr_pool_t *pool, char *name, mapcache_compression_type compression);
/**
* \brief create a format capable of creating quantized png
* \memberof mapcache_image_format_png_q
* @param pool
* @param name
* @param compression the ZLIB compression to apply
* @param ncolors the number of colors to quantize with
* @return
*/
mapcache_image_format* mapcache_imageio_create_png_q_format(apr_pool_t *pool, char *name, mapcache_compression_type compression, int ncolors);
/** @} */
/**\defgroup imageio_jpg JPEG Image IO
* \ingroup imageio */
/** @{ */
/**\class mapcache_image_format_jpeg
* \brief JPEG image format
* \extends mapcache_image_format
*/
struct mapcache_image_format_jpeg {
mapcache_image_format format;
int quality; /**< JPEG quality, 1-100 */
mapcache_photometric photometric;
mapcache_optimization optimize;
};
mapcache_image_format* mapcache_imageio_create_jpeg_format(apr_pool_t *pool, char *name, int quality,
mapcache_photometric photometric, mapcache_optimization optimize);
/**
* @param r
* @param buffer
* @return
*/
mapcache_image* _mapcache_imageio_jpeg_decode(mapcache_context *ctx, mapcache_buffer *buffer);
/**
* @param r
* @param buffer
* @return
*/
void _mapcache_imageio_jpeg_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer,
mapcache_image *image);
/** @} */
/**
* \brief lookup the first few bytes of a buffer to check for a known image format
*/
mapcache_image_format_type mapcache_imageio_header_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
/**
* \brief lookup the first few bytes of a buffer to check for alpha channel
*/
mapcache_image_alpha_type mapcache_imageio_alpha_sniff(mapcache_context *ctx, mapcache_buffer *buffer);
/**
* \brief checks if the given buffer is a recognized image format
*/
int mapcache_imageio_is_valid_format(mapcache_context *ctx, mapcache_buffer *buffer);
/**
* decodes given buffer
*/
mapcache_image* mapcache_imageio_decode(mapcache_context *ctx, mapcache_buffer *buffer);
/**
* decodes given buffer to an allocated image
*/
void mapcache_imageio_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer, mapcache_image *image);
/** @} */
typedef struct {
double start;
double end;
double resolution;
} mapcache_interval;
struct mapcache_requested_dimension {
mapcache_dimension *dimension;
char *requested_value;
char *cached_value;
apr_array_header_t *cached_entries_for_value;
};
void mapcache_tile_set_cached_dimension(mapcache_context *ctx, mapcache_tile *tile, const char *name, const char *value);
void mapcache_map_set_cached_dimension(mapcache_context *ctx, mapcache_map *map, const char *name, const char *value);
void mapcache_tile_set_requested_dimension(mapcache_context *ctx, mapcache_tile *tile, const char *name, const char *value);
void mapcache_map_set_requested_dimension(mapcache_context *ctx, mapcache_map *map, const char *name, const char *value);
MS_DLL_EXPORT void mapcache_set_requested_dimension(mapcache_context *ctx, apr_array_header_t *dimensions, const char *name, const char *value);
MS_DLL_EXPORT void mapcache_set_cached_dimension(mapcache_context *ctx, apr_array_header_t *dimensions, const char *name, const char *value);
MS_DLL_EXPORT apr_array_header_t *mapcache_requested_dimensions_clone(apr_pool_t *pool, apr_array_header_t *src);
struct mapcache_dimension {
mapcache_dimension_type type;
const char *class_name;
int isTime;
int wms_querybymap_minzoom;
char *name;
char *unit;
apr_table_t *metadata;
char *default_value;
/**
* \brief return the list of dimension values that match the requested entry
*/
apr_array_header_t* (*_get_entries_for_value)(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
/**
* \brief return the list of dimension values that match the requested time range
*/
apr_array_header_t* (*_get_entries_for_time_range)(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
time_t start, time_t end,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
/**
* \brief return all possible values
*/
apr_array_header_t* (*get_all_entries)(mapcache_context *ctx, mapcache_dimension *dimension,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
/**
* \brief return all possible values formatted in a way compatible with OGC capabilities element
*/
apr_array_header_t* (*get_all_ogc_formatted_entries)(mapcache_context *ctx, mapcache_dimension *dimension,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
/**
* \brief return all value to override default value
*/
apr_array_header_t* (*get_default_value)(mapcache_context *ctx, mapcache_dimension *dimension,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
/**
* \brief parse the value given in the configuration
*/
void (*configuration_parse_xml)(mapcache_context *context, mapcache_dimension *dim, ezxml_t node);
};
mapcache_dimension* mapcache_dimension_values_create(mapcache_context *ctx, apr_pool_t *pool);
mapcache_dimension* mapcache_dimension_sqlite_create(mapcache_context *ctx, apr_pool_t *pool);
mapcache_dimension* mapcache_dimension_postgresql_create(mapcache_context *ctx, apr_pool_t *pool);
mapcache_dimension* mapcache_dimension_regex_create(mapcache_context *ctx, apr_pool_t *pool);
mapcache_dimension* mapcache_dimension_time_create(mapcache_context *ctx, apr_pool_t *pool);
mapcache_dimension* mapcache_dimension_elasticsearch_create(mapcache_context *ctx, apr_pool_t *pool);
MS_DLL_EXPORT apr_array_header_t* mapcache_dimension_get_entries_for_value(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
apr_array_header_t* mapcache_dimension_time_get_entries_for_value(mapcache_context *ctx, mapcache_dimension *dimension, const char *value,
mapcache_tileset *tileset, mapcache_extent *extent, mapcache_grid *grid);
int mapcache_is_axis_inverted(const char *srs);
typedef struct mapcache_pooled_connection_container mapcache_pooled_connection_container;
typedef struct mapcache_pooled_connection mapcache_pooled_connection;
typedef struct mapcache_pooled_connection_private_data mapcache_pooled_connection_private_data;
struct mapcache_pooled_connection {
mapcache_pooled_connection_private_data *private;
void *connection;
};
typedef void (*mapcache_connection_constructor)(mapcache_context *ctx, void **connection, void *params);
typedef void (*mapcache_connection_destructor)(void *connection);
MS_DLL_EXPORT apr_status_t mapcache_connection_pool_create(mapcache_cfg *cfg, mapcache_connection_pool **cp, apr_pool_t *server_pool);
mapcache_pooled_connection* mapcache_connection_pool_get_connection(mapcache_context *ctx, char *key,
mapcache_connection_constructor constructor,
mapcache_connection_destructor destructor,
void *params);
void mapcache_connection_pool_invalidate_connection(mapcache_context *ctx, mapcache_pooled_connection *connection);
void mapcache_connection_pool_release_connection(mapcache_context *ctx, mapcache_pooled_connection *connection);
#endif /* MAPCACHE_H_ */
/* vim: ts=2 sts=2 et sw=2
*/
mapcache-rel-1-14-1/include/mapcache_services.h 0000664 0000000 0000000 00000011334 14653160677 0021376 0 ustar 00root root 0000000 0000000 /******************************************************************************
*
* Project: MapCache
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2016 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
/*! \file mapcache_services.h
\brief structure declarations for supported services
*/
#ifndef MAPCACHE_SERVICES_H_
#define MAPCACHE_SERVICES_H_
#include "mapcache.h"
/** \addtogroup services */
/** @{ */
typedef struct mapcache_request_get_capabilities_wmts mapcache_request_get_capabilities_wmts;
typedef struct mapcache_service_wmts mapcache_service_wmts;
struct mapcache_request_get_capabilities_wmts {
mapcache_request_get_capabilities request;
};
/**\class mapcache_service_wmts
* \brief a WMTS service
* \implements mapcache_service
*/
struct mapcache_service_wmts {
mapcache_service service;
};
typedef struct mapcache_service_wms mapcache_service_wms;
typedef struct mapcache_request_get_capabilities_wms mapcache_request_get_capabilities_wms;
struct mapcache_request_get_capabilities_wms {
mapcache_request_get_capabilities request;
};
/**\class mapcache_service_wms
* \brief an OGC WMS service
* \implements mapcache_service
*/
struct mapcache_service_wms {
mapcache_service service;
int maxsize;
apr_array_header_t *forwarding_rules;
mapcache_getmap_strategy getmap_strategy;
mapcache_resample_mode resample_mode;
mapcache_image_format *getmap_format;
int allow_format_override; /* can the client specify which image format should be returned */
};
typedef struct mapcache_service_ve mapcache_service_ve;
/**\class mapcache_service_ve
* \brief a virtualearth service
* \implements mapcache_service
*/
struct mapcache_service_ve {
mapcache_service service;
};
typedef struct mapcache_service_gmaps mapcache_service_gmaps;
typedef struct mapcache_service_tms mapcache_service_tms;
typedef struct mapcache_request_get_capabilities_tms mapcache_request_get_capabilities_tms;
/**\class mapcache_service_tms
* \brief a TMS service
* \implements mapcache_service
*/
struct mapcache_service_tms {
mapcache_service service;
int reverse_y;
};
struct mapcache_request_get_capabilities_tms {
mapcache_request_get_capabilities request;
mapcache_tileset *tileset;
mapcache_grid_link *grid_link;
char *version;
};
typedef struct mapcache_service_mapguide mapcache_service_mapguide;
struct mapcache_service_mapguide {
mapcache_service service;
int rows_per_folder;
int cols_per_folder;
};
typedef struct mapcache_service_kml mapcache_service_kml;
typedef struct mapcache_request_get_capabilities_kml mapcache_request_get_capabilities_kml;
struct mapcache_request_get_capabilities_kml {
mapcache_request_get_capabilities request;
mapcache_tile *tile;
mapcache_tileset *tileset;
mapcache_grid_link *grid;
};
/**\class mapcache_service_kml
* \brief a KML superoverlay service
* \implements mapcache_service
*/
struct mapcache_service_kml {
mapcache_service service;
};
typedef struct mapcache_request_get_capabilities_demo mapcache_request_get_capabilities_demo;
typedef struct mapcache_service_demo mapcache_service_demo;
/**
* the capabilities request for a specific service, to be able to create
* demo pages specific to a given service
*/
struct mapcache_request_get_capabilities_demo {
mapcache_request_get_capabilities request;
mapcache_service *service;
};
/**\class mapcache_service_demo
* \brief a demo service
* \implements mapcache_service
*/
struct mapcache_service_demo {
mapcache_service service;
};
#endif /*MAPCACHE_SERVICES_H*/
mapcache-rel-1-14-1/include/util.h 0000664 0000000 0000000 00000006602 14653160677 0016711 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include
#include
#ifndef UTIL_H_
#define UTIL_H_
#define MAPCACHE_MAX(a,b) (((a)>(b))?(a):(b))
#define MAPCACHE_MIN(a,b) (((a)<(b))?(a):(b))
#ifndef APR_ARRAY_IDX
#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
#endif
#ifndef APR_ARRAY_PUSH
#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
#endif
#if APR_MAJOR_VERSION < 1 || (APR_MAJOR_VERSION < 2 && APR_MINOR_VERSION < 3)
/**
* Create a new table whose contents are deep copied from the given
* table. A deep copy operation copies all fields, and makes copies
* of dynamically allocated memory pointed to by the fields.
* @param p The pool to allocate the new table out of
* @param t The table to clone
* @return A deep copy of the table passed in
*/
APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p,
const apr_table_t *t);
#endif
#if APR_MAJOR_VERSION < 1
#ifndef APR_FOPEN_READ
#define APR_FOPEN_READ APR_READ
#endif
#ifndef APR_FOPEN_BUFFERED
#define APR_FOPEN_BUFFERED APR_BUFFERED
#endif
#ifndef APR_FOPEN_BINARY
#define APR_FOPEN_BINARY APR_BINARY
#endif
#ifndef APR_FOPEN_CREATE
#define APR_FOPEN_CREATE APR_CREATE
#endif
#ifndef APR_FOPEN_WRITE
#define APR_FOPEN_WRITE APR_WRITE
#endif
#ifndef APR_FOPEN_SHARELOCK
#define APR_FOPEN_SHARELOCK APR_SHARELOCK
#endif
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
# define MS_DLL_EXPORT __declspec(dllexport)
#else
#define MS_DLL_EXPORT
#endif
#if defined(_WIN32)
struct mctimeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
MS_DLL_EXPORT void mapcache_gettimeofday(struct mctimeval *t, void *__not_used_here__);
MS_DLL_EXPORT char * strptime (const char *buf, const char *format, struct tm *timeptr);
#else
# include /* for gettimeofday() */
# define mctimeval timeval
# define mapcache_gettimeofday(t,u) gettimeofday(t,u)
#endif
#endif /* UTIL_H_ */
/* vim: ts=2 sts=2 et sw=2
*/
mapcache-rel-1-14-1/lib/ 0000775 0000000 0000000 00000000000 14653160677 0014702 5 ustar 00root root 0000000 0000000 mapcache-rel-1-14-1/lib/axisorder.c 0000664 0000000 0000000 00000054403 14653160677 0017054 0 ustar 00root root 0000000 0000000 /******************************************************************************
* $Id$
*
* Project: MapServer
* Purpose: Axis lookup table
* Author: Thomas Bonfort and the MapServer team.
*
******************************************************************************
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of this Software or works derived from this Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include "mapcache.h"
static struct axisOrientationEpsgCodes_s {
int code;
} axisOrientationEpsgCodes[] = {
{ 4326 },
{ 4258 },
{ 31466 },
{ 31467 },
{ 31468 },
{ 31469 },
{ 2166 },
{ 2167 },
{ 2168 },
{ 2036 },
{ 2044 },
{ 2045 },
{ 2065 },
{ 2081 },
{ 2082 },
{ 2083 },
{ 2085 },
{ 2086 },
{ 2091 },
{ 2092 },
{ 2093 },
{ 2096 },
{ 2097 },
{ 2098 },
{ 2105 },
{ 2106 },
{ 2107 },
{ 2108 },
{ 2109 },
{ 2110 },
{ 2111 },
{ 2112 },
{ 2113 },
{ 2114 },
{ 2115 },
{ 2116 },
{ 2117 },
{ 2118 },
{ 2119 },
{ 2120 },
{ 2121 },
{ 2122 },
{ 2123 },
{ 2124 },
{ 2125 },
{ 2126 },
{ 2127 },
{ 2128 },
{ 2129 },
{ 2130 },
{ 2131 },
{ 2132 },
{ 2169 },
{ 2170 },
{ 2171 },
{ 2172 },
{ 2173 },
{ 2174 },
{ 2175 },
{ 2176 },
{ 2177 },
{ 2178 },
{ 2179 },
{ 2180 },
{ 2193 },
{ 2199 },
{ 2200 },
{ 2206 },
{ 2207 },
{ 2208 },
{ 2209 },
{ 2210 },
{ 2211 },
{ 2212 },
{ 2319 },
{ 2320 },
{ 2321 },
{ 2322 },
{ 2323 },
{ 2324 },
{ 2325 },
{ 2326 },
{ 2327 },
{ 2328 },
{ 2329 },
{ 2330 },
{ 2331 },
{ 2332 },
{ 2333 },
{ 2334 },
{ 2335 },
{ 2336 },
{ 2337 },
{ 2338 },
{ 2339 },
{ 2340 },
{ 2341 },
{ 2342 },
{ 2343 },
{ 2344 },
{ 2345 },
{ 2346 },
{ 2347 },
{ 2348 },
{ 2349 },
{ 2350 },
{ 2351 },
{ 2352 },
{ 2353 },
{ 2354 },
{ 2355 },
{ 2356 },
{ 2357 },
{ 2358 },
{ 2359 },
{ 2360 },
{ 2361 },
{ 2362 },
{ 2363 },
{ 2364 },
{ 2365 },
{ 2366 },
{ 2367 },
{ 2368 },
{ 2369 },
{ 2370 },
{ 2371 },
{ 2372 },
{ 2373 },
{ 2374 },
{ 2375 },
{ 2376 },
{ 2377 },
{ 2378 },
{ 2379 },
{ 2380 },
{ 2381 },
{ 2382 },
{ 2383 },
{ 2384 },
{ 2385 },
{ 2386 },
{ 2387 },
{ 2388 },
{ 2389 },
{ 2390 },
{ 2391 },
{ 2392 },
{ 2393 },
{ 2394 },
{ 2395 },
{ 2396 },
{ 2397 },
{ 2398 },
{ 2399 },
{ 2400 },
{ 2401 },
{ 2402 },
{ 2403 },
{ 2404 },
{ 2405 },
{ 2406 },
{ 2407 },
{ 2408 },
{ 2409 },
{ 2410 },
{ 2411 },
{ 2412 },
{ 2413 },
{ 2414 },
{ 2415 },
{ 2416 },
{ 2417 },
{ 2418 },
{ 2419 },
{ 2420 },
{ 2421 },
{ 2422 },
{ 2423 },
{ 2424 },
{ 2425 },
{ 2426 },
{ 2427 },
{ 2428 },
{ 2429 },
{ 2430 },
{ 2431 },
{ 2432 },
{ 2433 },
{ 2434 },
{ 2435 },
{ 2436 },
{ 2437 },
{ 2438 },
{ 2439 },
{ 2440 },
{ 2441 },
{ 2442 },
{ 2443 },
{ 2444 },
{ 2445 },
{ 2446 },
{ 2447 },
{ 2448 },
{ 2449 },
{ 2450 },
{ 2451 },
{ 2452 },
{ 2453 },
{ 2454 },
{ 2455 },
{ 2456 },
{ 2457 },
{ 2458 },
{ 2459 },
{ 2460 },
{ 2461 },
{ 2462 },
{ 2463 },
{ 2464 },
{ 2465 },
{ 2466 },
{ 2467 },
{ 2468 },
{ 2469 },
{ 2470 },
{ 2471 },
{ 2472 },
{ 2473 },
{ 2474 },
{ 2475 },
{ 2476 },
{ 2477 },
{ 2478 },
{ 2479 },
{ 2480 },
{ 2481 },
{ 2482 },
{ 2483 },
{ 2484 },
{ 2485 },
{ 2486 },
{ 2487 },
{ 2488 },
{ 2489 },
{ 2490 },
{ 2491 },
{ 2492 },
{ 2493 },
{ 2494 },
{ 2495 },
{ 2496 },
{ 2497 },
{ 2498 },
{ 2499 },
{ 2500 },
{ 2501 },
{ 2502 },
{ 2503 },
{ 2504 },
{ 2505 },
{ 2506 },
{ 2507 },
{ 2508 },
{ 2509 },
{ 2510 },
{ 2511 },
{ 2512 },
{ 2513 },
{ 2514 },
{ 2515 },
{ 2516 },
{ 2517 },
{ 2518 },
{ 2519 },
{ 2520 },
{ 2521 },
{ 2522 },
{ 2523 },
{ 2524 },
{ 2525 },
{ 2526 },
{ 2527 },
{ 2528 },
{ 2529 },
{ 2530 },
{ 2531 },
{ 2532 },
{ 2533 },
{ 2534 },
{ 2535 },
{ 2536 },
{ 2537 },
{ 2538 },
{ 2539 },
{ 2540 },
{ 2541 },
{ 2542 },
{ 2543 },
{ 2544 },
{ 2545 },
{ 2546 },
{ 2547 },
{ 2548 },
{ 2549 },
{ 2551 },
{ 2552 },
{ 2553 },
{ 2554 },
{ 2555 },
{ 2556 },
{ 2557 },
{ 2558 },
{ 2559 },
{ 2560 },
{ 2561 },
{ 2562 },
{ 2563 },
{ 2564 },
{ 2565 },
{ 2566 },
{ 2567 },
{ 2568 },
{ 2569 },
{ 2570 },
{ 2571 },
{ 2572 },
{ 2573 },
{ 2574 },
{ 2575 },
{ 2576 },
{ 2577 },
{ 2578 },
{ 2579 },
{ 2580 },
{ 2581 },
{ 2582 },
{ 2583 },
{ 2584 },
{ 2585 },
{ 2586 },
{ 2587 },
{ 2588 },
{ 2589 },
{ 2590 },
{ 2591 },
{ 2592 },
{ 2593 },
{ 2594 },
{ 2595 },
{ 2596 },
{ 2597 },
{ 2598 },
{ 2599 },
{ 2600 },
{ 2601 },
{ 2602 },
{ 2603 },
{ 2604 },
{ 2605 },
{ 2606 },
{ 2607 },
{ 2608 },
{ 2609 },
{ 2610 },
{ 2611 },
{ 2612 },
{ 2613 },
{ 2614 },
{ 2615 },
{ 2616 },
{ 2617 },
{ 2618 },
{ 2619 },
{ 2620 },
{ 2621 },
{ 2622 },
{ 2623 },
{ 2624 },
{ 2625 },
{ 2626 },
{ 2627 },
{ 2628 },
{ 2629 },
{ 2630 },
{ 2631 },
{ 2632 },
{ 2633 },
{ 2634 },
{ 2635 },
{ 2636 },
{ 2637 },
{ 2638 },
{ 2639 },
{ 2640 },
{ 2641 },
{ 2642 },
{ 2643 },
{ 2644 },
{ 2645 },
{ 2646 },
{ 2647 },
{ 2648 },
{ 2649 },
{ 2650 },
{ 2651 },
{ 2652 },
{ 2653 },
{ 2654 },
{ 2655 },
{ 2656 },
{ 2657 },
{ 2658 },
{ 2659 },
{ 2660 },
{ 2661 },
{ 2662 },
{ 2663 },
{ 2664 },
{ 2665 },
{ 2666 },
{ 2667 },
{ 2668 },
{ 2669 },
{ 2670 },
{ 2671 },
{ 2672 },
{ 2673 },
{ 2674 },
{ 2675 },
{ 2676 },
{ 2677 },
{ 2678 },
{ 2679 },
{ 2680 },
{ 2681 },
{ 2682 },
{ 2683 },
{ 2684 },
{ 2685 },
{ 2686 },
{ 2687 },
{ 2688 },
{ 2689 },
{ 2690 },
{ 2691 },
{ 2692 },
{ 2693 },
{ 2694 },
{ 2695 },
{ 2696 },
{ 2697 },
{ 2698 },
{ 2699 },
{ 2700 },
{ 2701 },
{ 2702 },
{ 2703 },
{ 2704 },
{ 2705 },
{ 2706 },
{ 2707 },
{ 2708 },
{ 2709 },
{ 2710 },
{ 2711 },
{ 2712 },
{ 2713 },
{ 2714 },
{ 2715 },
{ 2716 },
{ 2717 },
{ 2718 },
{ 2719 },
{ 2720 },
{ 2721 },
{ 2722 },
{ 2723 },
{ 2724 },
{ 2725 },
{ 2726 },
{ 2727 },
{ 2728 },
{ 2729 },
{ 2730 },
{ 2731 },
{ 2732 },
{ 2733 },
{ 2734 },
{ 2735 },
{ 2738 },
{ 2739 },
{ 2740 },
{ 2741 },
{ 2742 },
{ 2743 },
{ 2744 },
{ 2745 },
{ 2746 },
{ 2747 },
{ 2748 },
{ 2749 },
{ 2750 },
{ 2751 },
{ 2752 },
{ 2753 },
{ 2754 },
{ 2755 },
{ 2756 },
{ 2757 },
{ 2758 },
{ 2935 },
{ 2936 },
{ 2937 },
{ 2938 },
{ 2939 },
{ 2940 },
{ 2941 },
{ 2953 },
{ 2963 },
{ 3006 },
{ 3007 },
{ 3008 },
{ 3009 },
{ 3010 },
{ 3011 },
{ 3012 },
{ 3013 },
{ 3014 },
{ 3015 },
{ 3016 },
{ 3017 },
{ 3018 },
{ 3019 },
{ 3020 },
{ 3021 },
{ 3022 },
{ 3023 },
{ 3024 },
{ 3025 },
{ 3026 },
{ 3027 },
{ 3028 },
{ 3029 },
{ 3030 },
{ 3034 },
{ 3035 },
{ 3038 },
{ 3039 },
{ 3040 },
{ 3041 },
{ 3042 },
{ 3043 },
{ 3044 },
{ 3045 },
{ 3046 },
{ 3047 },
{ 3048 },
{ 3049 },
{ 3050 },
{ 3051 },
{ 3058 },
{ 3059 },
{ 3068 },
{ 3114 },
{ 3115 },
{ 3116 },
{ 3117 },
{ 3118 },
{ 3120 },
{ 3126 },
{ 3127 },
{ 3128 },
{ 3129 },
{ 3130 },
{ 3131 },
{ 3132 },
{ 3133 },
{ 3134 },
{ 3135 },
{ 3136 },
{ 3137 },
{ 3138 },
{ 3139 },
{ 3140 },
{ 3146 },
{ 3147 },
{ 3150 },
{ 3151 },
{ 3152 },
{ 3300 },
{ 3301 },
{ 3328 },
{ 3329 },
{ 3330 },
{ 3331 },
{ 3332 },
{ 3333 },
{ 3334 },
{ 3335 },
{ 3346 },
{ 3350 },
{ 3351 },
{ 3352 },
{ 3366 },
{ 3386 },
{ 3387 },
{ 3388 },
{ 3389 },
{ 3390 },
{ 3396 },
{ 3397 },
{ 3398 },
{ 3399 },
{ 3407 },
{ 3414 },
{ 3416 },
{ 3764 },
{ 3788 },
{ 3789 },
{ 3790 },
{ 3791 },
{ 3793 },
{ 3795 },
{ 3796 },
{ 3819 },
{ 3821 },
{ 3823 },
{ 3824 },
{ 3833 },
{ 3834 },
{ 3835 },
{ 3836 },
{ 3837 },
{ 3838 },
{ 3839 },
{ 3840 },
{ 3841 },
{ 3842 },
{ 3843 },
{ 3844 },
{ 3845 },
{ 3846 },
{ 3847 },
{ 3848 },
{ 3849 },
{ 3850 },
{ 3851 },
{ 3852 },
{ 3854 },
{ 3873 },
{ 3874 },
{ 3875 },
{ 3876 },
{ 3877 },
{ 3878 },
{ 3879 },
{ 3880 },
{ 3881 },
{ 3882 },
{ 3883 },
{ 3884 },
{ 3885 },
{ 3888 },
{ 3889 },
{ 3906 },
{ 3907 },
{ 3908 },
{ 3909 },
{ 3910 },
{ 3911 },
{ 4001 },
{ 4002 },
{ 4003 },
{ 4004 },
{ 4005 },
{ 4006 },
{ 4007 },
{ 4008 },
{ 4009 },
{ 4010 },
{ 4011 },
{ 4012 },
{ 4013 },
{ 4014 },
{ 4015 },
{ 4016 },
{ 4017 },
{ 4018 },
{ 4019 },
{ 4020 },
{ 4021 },
{ 4022 },
{ 4023 },
{ 4024 },
{ 4025 },
{ 4026 },
{ 4027 },
{ 4028 },
{ 4029 },
{ 4030 },
{ 4031 },
{ 4032 },
{ 4033 },
{ 4034 },
{ 4035 },
{ 4036 },
{ 4037 },
{ 4038 },
{ 4040 },
{ 4041 },
{ 4042 },
{ 4043 },
{ 4044 },
{ 4045 },
{ 4046 },
{ 4047 },
{ 4052 },
{ 4053 },
{ 4054 },
{ 4055 },
{ 4074 },
{ 4075 },
{ 4080 },
{ 4081 },
{ 4120 },
{ 4121 },
{ 4122 },
{ 4123 },
{ 4124 },
{ 4125 },
{ 4126 },
{ 4127 },
{ 4128 },
{ 4129 },
{ 4130 },
{ 4131 },
{ 4132 },
{ 4133 },
{ 4134 },
{ 4135 },
{ 4136 },
{ 4137 },
{ 4138 },
{ 4139 },
{ 4140 },
{ 4141 },
{ 4142 },
{ 4143 },
{ 4144 },
{ 4145 },
{ 4146 },
{ 4147 },
{ 4148 },
{ 4149 },
{ 4150 },
{ 4151 },
{ 4152 },
{ 4153 },
{ 4154 },
{ 4155 },
{ 4156 },
{ 4157 },
{ 4158 },
{ 4159 },
{ 4160 },
{ 4161 },
{ 4162 },
{ 4163 },
{ 4164 },
{ 4165 },
{ 4166 },
{ 4167 },
{ 4168 },
{ 4169 },
{ 4170 },
{ 4171 },
{ 4172 },
{ 4173 },
{ 4174 },
{ 4175 },
{ 4176 },
{ 4178 },
{ 4179 },
{ 4180 },
{ 4181 },
{ 4182 },
{ 4183 },
{ 4184 },
{ 4185 },
{ 4188 },
{ 4189 },
{ 4190 },
{ 4191 },
{ 4192 },
{ 4193 },
{ 4194 },
{ 4195 },
{ 4196 },
{ 4197 },
{ 4198 },
{ 4199 },
{ 4200 },
{ 4201 },
{ 4202 },
{ 4203 },
{ 4204 },
{ 4205 },
{ 4206 },
{ 4207 },
{ 4208 },
{ 4209 },
{ 4210 },
{ 4211 },
{ 4212 },
{ 4213 },
{ 4214 },
{ 4215 },
{ 4216 },
{ 4218 },
{ 4219 },
{ 4220 },
{ 4221 },
{ 4222 },
{ 4223 },
{ 4224 },
{ 4225 },
{ 4226 },
{ 4227 },
{ 4228 },
{ 4229 },
{ 4230 },
{ 4231 },
{ 4232 },
{ 4233 },
{ 4234 },
{ 4235 },
{ 4236 },
{ 4237 },
{ 4238 },
{ 4239 },
{ 4240 },
{ 4241 },
{ 4242 },
{ 4243 },
{ 4244 },
{ 4245 },
{ 4246 },
{ 4247 },
{ 4248 },
{ 4249 },
{ 4250 },
{ 4251 },
{ 4252 },
{ 4253 },
{ 4254 },
{ 4255 },
{ 4256 },
{ 4257 },
{ 4259 },
{ 4260 },
{ 4261 },
{ 4262 },
{ 4263 },
{ 4264 },
{ 4265 },
{ 4266 },
{ 4267 },
{ 4268 },
{ 4269 },
{ 4270 },
{ 4271 },
{ 4272 },
{ 4273 },
{ 4274 },
{ 4275 },
{ 4276 },
{ 4277 },
{ 4278 },
{ 4279 },
{ 4280 },
{ 4281 },
{ 4282 },
{ 4283 },
{ 4284 },
{ 4285 },
{ 4286 },
{ 4287 },
{ 4288 },
{ 4289 },
{ 4291 },
{ 4292 },
{ 4293 },
{ 4294 },
{ 4295 },
{ 4296 },
{ 4297 },
{ 4298 },
{ 4299 },
{ 4300 },
{ 4301 },
{ 4302 },
{ 4303 },
{ 4304 },
{ 4306 },
{ 4307 },
{ 4308 },
{ 4309 },
{ 4310 },
{ 4311 },
{ 4312 },
{ 4313 },
{ 4314 },
{ 4315 },
{ 4316 },
{ 4317 },
{ 4318 },
{ 4319 },
{ 4322 },
{ 4324 },
{ 4327 },
{ 4329 },
{ 4339 },
{ 4341 },
{ 4343 },
{ 4345 },
{ 4347 },
{ 4349 },
{ 4351 },
{ 4353 },
{ 4355 },
{ 4357 },
{ 4359 },
{ 4361 },
{ 4363 },
{ 4365 },
{ 4367 },
{ 4369 },
{ 4371 },
{ 4373 },
{ 4375 },
{ 4377 },
{ 4379 },
{ 4381 },
{ 4383 },
{ 4386 },
{ 4388 },
{ 4417 },
{ 4434 },
{ 4463 },
{ 4466 },
{ 4469 },
{ 4470 },
{ 4472 },
{ 4475 },
{ 4480 },
{ 4482 },
{ 4483 },
{ 4490 },
{ 4491 },
{ 4492 },
{ 4493 },
{ 4494 },
{ 4495 },
{ 4496 },
{ 4497 },
{ 4498 },
{ 4499 },
{ 4500 },
{ 4501 },
{ 4502 },
{ 4503 },
{ 4504 },
{ 4505 },
{ 4506 },
{ 4507 },
{ 4508 },
{ 4509 },
{ 4510 },
{ 4511 },
{ 4512 },
{ 4513 },
{ 4514 },
{ 4515 },
{ 4516 },
{ 4517 },
{ 4518 },
{ 4519 },
{ 4520 },
{ 4521 },
{ 4522 },
{ 4523 },
{ 4524 },
{ 4525 },
{ 4526 },
{ 4527 },
{ 4528 },
{ 4529 },
{ 4530 },
{ 4531 },
{ 4532 },
{ 4533 },
{ 4534 },
{ 4535 },
{ 4536 },
{ 4537 },
{ 4538 },
{ 4539 },
{ 4540 },
{ 4541 },
{ 4542 },
{ 4543 },
{ 4544 },
{ 4545 },
{ 4546 },
{ 4547 },
{ 4548 },
{ 4549 },
{ 4550 },
{ 4551 },
{ 4552 },
{ 4553 },
{ 4554 },
{ 4555 },
{ 4557 },
{ 4558 },
{ 4568 },
{ 4569 },
{ 4570 },
{ 4571 },
{ 4572 },
{ 4573 },
{ 4574 },
{ 4575 },
{ 4576 },
{ 4577 },
{ 4578 },
{ 4579 },
{ 4580 },
{ 4581 },
{ 4582 },
{ 4583 },
{ 4584 },
{ 4585 },
{ 4586 },
{ 4587 },
{ 4588 },
{ 4589 },
{ 4600 },
{ 4601 },
{ 4602 },
{ 4603 },
{ 4604 },
{ 4605 },
{ 4606 },
{ 4607 },
{ 4608 },
{ 4609 },
{ 4610 },
{ 4611 },
{ 4612 },
{ 4613 },
{ 4614 },
{ 4615 },
{ 4616 },
{ 4617 },
{ 4618 },
{ 4619 },
{ 4620 },
{ 4621 },
{ 4622 },
{ 4623 },
{ 4624 },
{ 4625 },
{ 4626 },
{ 4627 },
{ 4628 },
{ 4629 },
{ 4630 },
{ 4631 },
{ 4632 },
{ 4633 },
{ 4634 },
{ 4635 },
{ 4636 },
{ 4637 },
{ 4638 },
{ 4639 },
{ 4640 },
{ 4641 },
{ 4642 },
{ 4643 },
{ 4644 },
{ 4645 },
{ 4646 },
{ 4652 },
{ 4653 },
{ 4654 },
{ 4655 },
{ 4656 },
{ 4657 },
{ 4658 },
{ 4659 },
{ 4660 },
{ 4661 },
{ 4662 },
{ 4663 },
{ 4664 },
{ 4665 },
{ 4666 },
{ 4667 },
{ 4668 },
{ 4669 },
{ 4670 },
{ 4671 },
{ 4672 },
{ 4673 },
{ 4674 },
{ 4675 },
{ 4676 },
{ 4677 },
{ 4678 },
{ 4679 },
{ 4680 },
{ 4681 },
{ 4682 },
{ 4683 },
{ 4684 },
{ 4685 },
{ 4686 },
{ 4687 },
{ 4688 },
{ 4689 },
{ 4690 },
{ 4691 },
{ 4692 },
{ 4693 },
{ 4694 },
{ 4695 },
{ 4696 },
{ 4697 },
{ 4698 },
{ 4699 },
{ 4700 },
{ 4701 },
{ 4702 },
{ 4703 },
{ 4704 },
{ 4705 },
{ 4706 },
{ 4707 },
{ 4708 },
{ 4709 },
{ 4710 },
{ 4711 },
{ 4712 },
{ 4713 },
{ 4714 },
{ 4715 },
{ 4716 },
{ 4717 },
{ 4718 },
{ 4719 },
{ 4720 },
{ 4721 },
{ 4722 },
{ 4723 },
{ 4724 },
{ 4725 },
{ 4726 },
{ 4727 },
{ 4728 },
{ 4729 },
{ 4730 },
{ 4731 },
{ 4732 },
{ 4733 },
{ 4734 },
{ 4735 },
{ 4736 },
{ 4737 },
{ 4738 },
{ 4739 },
{ 4740 },
{ 4741 },
{ 4742 },
{ 4743 },
{ 4744 },
{ 4745 },
{ 4746 },
{ 4747 },
{ 4748 },
{ 4749 },
{ 4750 },
{ 4751 },
{ 4752 },
{ 4753 },
{ 4754 },
{ 4755 },
{ 4756 },
{ 4757 },
{ 4758 },
{ 4759 },
{ 4760 },
{ 4761 },
{ 4762 },
{ 4763 },
{ 4764 },
{ 4765 },
{ 4766 },
{ 4767 },
{ 4768 },
{ 4769 },
{ 4770 },
{ 4771 },
{ 4772 },
{ 4773 },
{ 4774 },
{ 4775 },
{ 4776 },
{ 4777 },
{ 4778 },
{ 4779 },
{ 4780 },
{ 4781 },
{ 4782 },
{ 4783 },
{ 4784 },
{ 4785 },
{ 4786 },
{ 4787 },
{ 4788 },
{ 4789 },
{ 4790 },
{ 4791 },
{ 4792 },
{ 4793 },
{ 4794 },
{ 4795 },
{ 4796 },
{ 4797 },
{ 4798 },
{ 4799 },
{ 4800 },
{ 4801 },
{ 4802 },
{ 4803 },
{ 4804 },
{ 4805 },
{ 4806 },
{ 4807 },
{ 4808 },
{ 4809 },
{ 4810 },
{ 4811 },
{ 4812 },
{ 4813 },
{ 4814 },
{ 4815 },
{ 4816 },
{ 4817 },
{ 4818 },
{ 4819 },
{ 4820 },
{ 4821 },
{ 4822 },
{ 4823 },
{ 4824 },
{ 4839 },
{ 4855 },
{ 4856 },
{ 4857 },
{ 4858 },
{ 4859 },
{ 4860 },
{ 4861 },
{ 4862 },
{ 4863 },
{ 4864 },
{ 4865 },
{ 4866 },
{ 4867 },
{ 4868 },
{ 4869 },
{ 4870 },
{ 4871 },
{ 4872 },
{ 4873 },
{ 4874 },
{ 4875 },
{ 4876 },
{ 4877 },
{ 4878 },
{ 4879 },
{ 4880 },
{ 4883 },
{ 4885 },
{ 4887 },
{ 4889 },
{ 4891 },
{ 4893 },
{ 4895 },
{ 4898 },
{ 4900 },
{ 4901 },
{ 4902 },
{ 4903 },
{ 4904 },
{ 4907 },
{ 4909 },
{ 4921 },
{ 4923 },
{ 4925 },
{ 4927 },
{ 4929 },
{ 4931 },
{ 4933 },
{ 4935 },
{ 4937 },
{ 4939 },
{ 4941 },
{ 4943 },
{ 4945 },
{ 4947 },
{ 4949 },
{ 4951 },
{ 4953 },
{ 4955 },
{ 4957 },
{ 4959 },
{ 4961 },
{ 4963 },
{ 4965 },
{ 4967 },
{ 4969 },
{ 4971 },
{ 4973 },
{ 4975 },
{ 4977 },
{ 4979 },
{ 4981 },
{ 4983 },
{ 4985 },
{ 4987 },
{ 4989 },
{ 4991 },
{ 4993 },
{ 4995 },
{ 4997 },
{ 4999 },
{ 5012 },
{ 5013 },
{ 5017 },
{ 5048 },
{ 5105 },
{ 5106 },
{ 5107 },
{ 5108 },
{ 5109 },
{ 5110 },
{ 5111 },
{ 5112 },
{ 5113 },
{ 5114 },
{ 5115 },
{ 5116 },
{ 5117 },
{ 5118 },
{ 5119 },
{ 5120 },
{ 5121 },
{ 5122 },
{ 5123 },
{ 5124 },
{ 5125 },
{ 5126 },
{ 5127 },
{ 5128 },
{ 5129 },
{ 5130 },
{ 5132 },
{ 5167 },
{ 5168 },
{ 5169 },
{ 5170 },
{ 5171 },
{ 5172 },
{ 5173 },
{ 5174 },
{ 5175 },
{ 5176 },
{ 5177 },
{ 5178 },
{ 5179 },
{ 5180 },
{ 5181 },
{ 5182 },
{ 5183 },
{ 5184 },
{ 5185 },
{ 5186 },
{ 5187 },
{ 5188 },
{ 5224 },
{ 5228 },
{ 5229 },
{ 5233 },
{ 5245 },
{ 5246 },
{ 5251 },
{ 5252 },
{ 5253 },
{ 5254 },
{ 5255 },
{ 5256 },
{ 5257 },
{ 5258 },
{ 5259 },
{ 5263 },
{ 5264 },
{ 5269 },
{ 5270 },
{ 5271 },
{ 5272 },
{ 5273 },
{ 5274 },
{ 5275 },
{ 5801 },
{ 5802 },
{ 5803 },
{ 5804 },
{ 5808 },
{ 5809 },
{ 5810 },
{ 5811 },
{ 5812 },
{ 5813 },
{ 5814 },
{ 5815 },
{ 5816 },
{ 20004 },
{ 20005 },
{ 20006 },
{ 20007 },
{ 20008 },
{ 20009 },
{ 20010 },
{ 20011 },
{ 20012 },
{ 20013 },
{ 20014 },
{ 20015 },
{ 20016 },
{ 20017 },
{ 20018 },
{ 20019 },
{ 20020 },
{ 20021 },
{ 20022 },
{ 20023 },
{ 20024 },
{ 20025 },
{ 20026 },
{ 20027 },
{ 20028 },
{ 20029 },
{ 20030 },
{ 20031 },
{ 20032 },
{ 20064 },
{ 20065 },
{ 20066 },
{ 20067 },
{ 20068 },
{ 20069 },
{ 20070 },
{ 20071 },
{ 20072 },
{ 20073 },
{ 20074 },
{ 20075 },
{ 20076 },
{ 20077 },
{ 20078 },
{ 20079 },
{ 20080 },
{ 20081 },
{ 20082 },
{ 20083 },
{ 20084 },
{ 20085 },
{ 20086 },
{ 20087 },
{ 20088 },
{ 20089 },
{ 20090 },
{ 20091 },
{ 20092 },
{ 21413 },
{ 21414 },
{ 21415 },
{ 21416 },
{ 21417 },
{ 21418 },
{ 21419 },
{ 21420 },
{ 21421 },
{ 21422 },
{ 21423 },
{ 21453 },
{ 21454 },
{ 21455 },
{ 21456 },
{ 21457 },
{ 21458 },
{ 21459 },
{ 21460 },
{ 21461 },
{ 21462 },
{ 21463 },
{ 21473 },
{ 21474 },
{ 21475 },
{ 21476 },
{ 21477 },
{ 21478 },
{ 21479 },
{ 21480 },
{ 21481 },
{ 21482 },
{ 21483 },
{ 21896 },
{ 21897 },
{ 21898 },
{ 21899 },
{ 22171 },
{ 22172 },
{ 22173 },
{ 22174 },
{ 22175 },
{ 22176 },
{ 22177 },
{ 22181 },
{ 22182 },
{ 22183 },
{ 22184 },
{ 22185 },
{ 22186 },
{ 22187 },
{ 22191 },
{ 22192 },
{ 22193 },
{ 22194 },
{ 22195 },
{ 22196 },
{ 22197 },
{ 25884 },
{ 27205 },
{ 27206 },
{ 27207 },
{ 27208 },
{ 27209 },
{ 27210 },
{ 27211 },
{ 27212 },
{ 27213 },
{ 27214 },
{ 27215 },
{ 27216 },
{ 27217 },
{ 27218 },
{ 27219 },
{ 27220 },
{ 27221 },
{ 27222 },
{ 27223 },
{ 27224 },
{ 27225 },
{ 27226 },
{ 27227 },
{ 27228 },
{ 27229 },
{ 27230 },
{ 27231 },
{ 27232 },
{ 27391 },
{ 27392 },
{ 27393 },
{ 27394 },
{ 27395 },
{ 27396 },
{ 27397 },
{ 27398 },
{ 27492 },
{ 28402 },
{ 28403 },
{ 28404 },
{ 28405 },
{ 28406 },
{ 28407 },
{ 28408 },
{ 28409 },
{ 28410 },
{ 28411 },
{ 28412 },
{ 28413 },
{ 28414 },
{ 28415 },
{ 28416 },
{ 28417 },
{ 28418 },
{ 28419 },
{ 28420 },
{ 28421 },
{ 28422 },
{ 28423 },
{ 28424 },
{ 28425 },
{ 28426 },
{ 28427 },
{ 28428 },
{ 28429 },
{ 28430 },
{ 28431 },
{ 28432 },
{ 28462 },
{ 28463 },
{ 28464 },
{ 28465 },
{ 28466 },
{ 28467 },
{ 28468 },
{ 28469 },
{ 28470 },
{ 28471 },
{ 28472 },
{ 28473 },
{ 28474 },
{ 28475 },
{ 28476 },
{ 28477 },
{ 28478 },
{ 28479 },
{ 28480 },
{ 28481 },
{ 28482 },
{ 28483 },
{ 28484 },
{ 28485 },
{ 28486 },
{ 28487 },
{ 28488 },
{ 28489 },
{ 28490 },
{ 28491 },
{ 28492 },
{ 29701 },
{ 29702 },
{ 30161 },
{ 30162 },
{ 30163 },
{ 30164 },
{ 30165 },
{ 30166 },
{ 30167 },
{ 30168 },
{ 30169 },
{ 30170 },
{ 30171 },
{ 30172 },
{ 30173 },
{ 30174 },
{ 30175 },
{ 30176 },
{ 30177 },
{ 30178 },
{ 30179 },
{ 30800 },
{ 31251 },
{ 31252 },
{ 31253 },
{ 31254 },
{ 31255 },
{ 31256 },
{ 31257 },
{ 31258 },
{ 31259 },
{ 31275 },
{ 31276 },
{ 31277 },
{ 31278 },
{ 31279 },
{ 31281 },
{ 31282 },
{ 31283 },
{ 31284 },
{ 31285 },
{ 31286 },
{ 31287 },
{ 31288 },
{ 31289 },
{ 31290 },
{ 31700 },
};
#define AXIS_ORIENTATION_TABLE_SIZE 1703
int mapcache_is_axis_inverted(const char *srs)
{
int i,code;
if(strncasecmp(srs,"epsg:",5) || strlen(srs)<6) {
/* if we don't have an epsg formated srs */
return MAPCACHE_FALSE;
}
code = atoi(&(srs[5]));
/*check the static table*/
for (i=0; i