[ossim] 01/04: New upstream version 2.2.2
Bas Couwenberg
sebastic at debian.org
Wed Feb 7 18:09:17 UTC 2018
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository ossim.
commit 851b6bc21e8baf2d78c257e580f29e61cd9653a1
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Wed Feb 7 18:40:59 2018 +0100
New upstream version 2.2.2
---
CMakeLists.txt | 10 +
cmake/CMakeLists.txt | 10 +-
cmake/scripts/ossim-cmake-config.sh | 17 +-
include/ossim/base/JsonInterface.h | 31 +
include/ossim/base/ossimKeywordlist.h | 27 +-
include/ossim/imaging/ossimWriter.h | 111 ++-
include/ossim/init/JsonConfig.h | 184 +++++
include/ossim/projection/ossimImageViewTransform.h | 8 +-
include/ossim/projection/ossimRpcSolver.h | 7 +-
include/ossim/projection/ossimSensorModel.h | 2 +-
include/ossim/projection/ossimSensorModelTuple.h | 2 +-
include/ossim/reg/GroundControlPoint.h | 83 +++
include/ossim/reg/Image.h | 85 +++
include/ossim/reg/PhotoBlock.h | 99 +++
include/ossim/reg/TiePoint.h | 126 ++++
include/ossim/util/ossimTool.h | 16 +-
scripts/archive.sh | 2 +-
scripts/build.sh | 7 +-
scripts/env.sh | 2 +-
scripts/install.sh | 2 +-
share/ossim/templates/ossim_preferences_template | 5 +-
src/CMakeLists.txt | 9 +-
src/base/ossimKeywordlist.cpp | 425 +++++++++++-
src/imaging/ossimImageRenderer.cpp | 27 +-
src/imaging/ossimImageWriterFactory.cpp | 5 +-
src/imaging/ossimWriter.cpp | 746 +++++++++++++++------
src/init/JsonConfig.cpp | 467 +++++++++++++
src/projection/ossimImageViewTransform.cpp | 15 +
src/projection/ossimRpcModel.cpp | 3 +-
src/projection/ossimSensorModel.cpp | 4 +-
src/projection/ossimSensorModelTuple.cpp | 197 +++---
src/reg/GroundControlPoint.cpp | 121 ++++
src/reg/Image.cpp | 115 ++++
src/reg/PhotoBlock.cpp | 183 +++++
src/reg/TiePoint.cpp | 243 +++++++
src/support_data/ossimQuickbirdRpcHeader.cpp | 12 +
src/util/ossimTool.cpp | 5 -
37 files changed, 3051 insertions(+), 362 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c3a4bb..f619f1b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,6 +103,16 @@ else( TIFF_FOUND )
message( FATAL_ERROR "Could not find required tiff package!" )
endif( TIFF_FOUND )
+# JSONCPP - Required:
+find_package( JsonCpp )
+if( JSONCPP_FOUND )
+ include_directories( ${JSONCPP_INCLUDE_DIR} )
+ set( ossimDependentLibs ${ossimDependentLibs} ${JSONCPP_LIBRARY} )
+ message("Found JsonCpp" )
+else( JSONCPP_FOUND )
+ message( FATAL_ERROR "Could not find required JsonCpp package!" )
+endif( JSONCPP_FOUND )
+
# This caused a core dump on ossim executables running in jenins pipeline (ossim-test-dev)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
find_library( DL_LIBRARY dl )
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 1dd79f1..91a2e95 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -122,8 +122,8 @@ IF(BUILD_OSSIM_VIDEO AND EXISTS ${OSSIM_DEV_HOME}/ossim-video)
add_subdirectory(${OSSIM_DEV_HOME}/ossim-video ${CMAKE_CURRENT_BINARY_DIR}/ossim-video)
ENDIF()
-IF(BUILD_ISA_PLUGIN AND EXISTS ${OSSIM_DEV_HOME}/ossim-isa-plugin)
- add_subdirectory(${OSSIM_DEV_HOME}/ossim-isa-plugin ${CMAKE_CURRENT_BINARY_DIR}/ossim-isa-plugin)
+IF(BUILD_MSP_PLUGIN AND EXISTS ${OSSIM_DEV_HOME}/ossim-msp-plugin)
+ add_subdirectory(${OSSIM_DEV_HOME}/ossim-msp-plugin ${CMAKE_CURRENT_BINARY_DIR}/ossim-msp-plugin)
ENDIF()
IF(BUILD_CSM_PLUGIN AND EXISTS ${OSSIM_DEV_HOME}/ossim-csm-plugin)
@@ -188,6 +188,10 @@ IF(BUILD_DSMG AND EXISTS ${OSSIM_DEV_HOME}/ossim-dsmg)
add_subdirectory(${OSSIM_DEV_HOME}/ossim-dsmg ${CMAKE_CURRENT_BINARY_DIR}/ossim-dsmg)
ENDIF()
+IF(BUILD_OSSIM_ISA AND EXISTS ${OSSIM_DEV_HOME}/ossim-isa)
+ add_subdirectory(${OSSIM_DEV_HOME}/ossim-isa ${CMAKE_CURRENT_BINARY_DIR}/ossim-isa)
+ENDIF()
+
############################## Doxygen installation for current ossim core module ###########################################
FIND_PACKAGE(Doxygen)
@@ -365,6 +369,6 @@ MESSAGE( STATUS "BUILD_OSSIM_WMS = ${BUILD_OSSIM_WMS}" )
MESSAGE( STATUS "BUILD_LIBRARY_DIR = ${BUILD_LIBRARY_DIR}" )
MESSAGE( STATUS "BUILD_RUNTIME_DIR = ${BUILD_RUNTIME_DIR}" )
MESSAGE( STATUS "BUILD_DSMG = ${BUILD_DSMG}" )
-MESSAGE( STATUS "BUILD_ISA_PLUGIN = ${BUILD_ISA_PLUGIN}" )
+MESSAGE( STATUS "BUILD_MSP_PLUGIN = ${BUILD_MSP_PLUGIN}" )
MESSAGE( STATUS "BUILD_CSM_PLUGIN = ${BUILD_CSM_PLUGIN}" )
MESSAGE( STATUS "Use OSSIM_BUILD_ADDITIONAL_DIRECTORIES to add other cmake builds." )
diff --git a/cmake/scripts/ossim-cmake-config.sh b/cmake/scripts/ossim-cmake-config.sh
index 799ed18..1944e05 100755
--- a/cmake/scripts/ossim-cmake-config.sh
+++ b/cmake/scripts/ossim-cmake-config.sh
@@ -7,7 +7,7 @@
# DO NOT RELOCATE THIS SCRIPT. Its location is used to resolve relative
# directory paths.
#
-# Usage: <this_script_name> [<build_type>]
+# Usage: <this_script_name> [<build_type>]
#
# where the optional <build_type> is one of the following literals
# (case-insensitive):
@@ -16,11 +16,11 @@
# "debug",
# "relWithDebInfo",
# "minSizeRel",
-# "eclipse"
+# "eclipse"
#
# If a build type = "eclipse" is specified, cmake will generate a Debug
# build environment along with Eclipse CDT4 project files (in the build
-# directory) for importing as existing project.
+# directory) for importing as existing project.
#
# Instructions: Run this script to build the repository. This script can be
# run from any directory, but will assume a default relative directory
@@ -147,6 +147,9 @@ if [ -z $BUILD_OSSIM_ISA ] ; then
fi
# Plugins:
+if [ -z $BUILD_ATP_PLUGIN ]; then
+ BUILD_ATP_PLUGIN=OFF
+fi
if [ -z $BUILD_CNES_PLUGIN ]; then
BUILD_CNES_PLUGIN=OFF
fi
@@ -165,8 +168,8 @@ fi
if [ -z $BUILD_HDF5_PLUGIN ]; then
BUILD_HDF5_PLUGIN=OFF
fi
-if [ -z $BUILD_ISA_PLUGIN ]; then
- BUILD_ISA_PLUGIN=OFF
+if [ -z $BUILD_MSP_PLUGIN ]; then
+ BUILD_MSP_PLUGIN=OFF
fi
if [ -z $BUILD_KAKADU_PLUGIN ]; then
BUILD_KAKADU_PLUGIN=OFF
@@ -251,10 +254,10 @@ cmake -G "$CMAKE_G_ARG" \
-DCMAKE_OSX_ARCHITECTURES="x86_64" \
-DCMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT \
-DCMAKE_OSX_DEPLOYMENT_TARGET=$CMAKE_OSX_DEPLOYMENT_TARGET \
--DCMAKE_ECLIPSE_VERSION=$CMAKE_ECLIPSE_VERSION \
-DBUILD_OSSIM_FRAMEWORKS=${BUILD_OSSIM_FRAMEWORKS} \
-DBUILD_OMS=$BUILD_OMS \
-DBUILD_OSSIM_PLANET_GUI=${BUILD_OSSIM_PLANET_GUI} \
+-DBUILD_ATP_PLUGIN=$BUILD_ATP_PLUGIN \
-DBUILD_CNES_PLUGIN=$BUILD_CNES_PLUGIN \
-DBUILD_CSM_PLUGIN=$BUILD_CSM_PLUGIN \
-DBUILD_DSMG=$BUILD_DSMG \
@@ -263,7 +266,7 @@ cmake -G "$CMAKE_G_ARG" \
-DBUILD_GEOPDF_PLUGIN=$BUILD_GEOPDF_PLUGIN \
-DBUILD_GDAL_PLUGIN=$BUILD_GDAL_PLUGIN \
-DBUILD_HDF5_PLUGIN=$BUILD_HDF5_PLUGIN \
--DBUILD_ISA_PLUGIN=$BUILD_ISA_PLUGIN \
+-DBUILD_MSP_PLUGIN=$BUILD_MSP_PLUGIN \
-DBUILD_KAKADU_PLUGIN=$BUILD_KAKADU_PLUGIN \
-DBUILD_JPEG12_PLUGIN=$BUILD_JPEG12_PLUGIN \
-DKAKADU_ROOT_SRC=$KAKADU_ROOT_SRC \
diff --git a/include/ossim/base/JsonInterface.h b/include/ossim/base/JsonInterface.h
new file mode 100644
index 0000000..43c368d
--- /dev/null
+++ b/include/ossim/base/JsonInterface.h
@@ -0,0 +1,31 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+#ifndef JsonInterface_HEADER
+#define JsonInterface_HEADER 1
+
+#include <json/json.h>
+
+namespace ossim {
+
+/**
+ * Pure virtual interface for classes implementing JSON-based load/save state..
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON formats used.
+ */
+class JsonInterface
+{
+public:
+ JsonInterface() {}
+ virtual ~JsonInterface() {}
+
+ virtual void loadJSON(const Json::Value& jsonNode) = 0;
+ virtual void saveJSON(Json::Value& jsonNode) const = 0;
+
+};
+
+}
+#endif
diff --git a/include/ossim/base/ossimKeywordlist.h b/include/ossim/base/ossimKeywordlist.h
index 4ebd618..553eb8a 100644
--- a/include/ossim/base/ossimKeywordlist.h
+++ b/include/ossim/base/ossimKeywordlist.h
@@ -339,7 +339,7 @@ public:
* or an empty string if the key was not found.
* @param key e.g. "number_line"
* @param prefix e..g "image0."
- * @return Reference to string. This will be emptry if not found or
+ * @return Reference to string. This will be empty if not found or
* if value is empty.
*/
const std::string& findKey(const std::string& key) const;
@@ -390,6 +390,20 @@ public:
virtual void writeToStream(std::ostream &out)const;
+ /**
+ * Outputs in xml format.
+ * @param out Stream to write to.
+ * @param rootTag name of the root XML element/tag
+ */
+ void toXML(std::ostream &out, const std::string& rootTag="info")const;
+
+ /**
+ * Outputs in json format.
+ * @param out Stream to write to.
+ * @param rootTag name of the root json element/tag
+ */
+ void toJSON(std::ostream &out, const std::string& rootTag="info")const;
+
virtual std::ostream& print(std::ostream& os) const;
OSSIMDLLEXPORT friend std::ostream& operator<<(std::ostream& os,
const ossimKeywordlist& kwl);
@@ -566,6 +580,17 @@ protected:
KeywordMap::iterator getMapEntry(const ossimString& key);
KeywordMap::iterator getMapEntry(const char* key);
+ // For toXML method lifted from oms::DataInfo.
+ bool isSpecialXmlCharacters(const ossimString& value) const;
+ bool isValidTag(const std::string& value)const;
+ void replaceSpecialCharacters(ossimString& value)const;
+
+ /**
+ * @return true if a == b, false if not.
+ */
+ bool isSame( const std::vector<ossimString>& a,
+ const std::vector<ossimString>& b ) const;
+
KeywordMap m_map;
char m_delimiter;
diff --git a/include/ossim/imaging/ossimWriter.h b/include/ossim/imaging/ossimWriter.h
index 5880b9c..062d6d5 100644
--- a/include/ossim/imaging/ossimWriter.h
+++ b/include/ossim/imaging/ossimWriter.h
@@ -2,8 +2,6 @@
//
// License: MIT
//
-// See LICENSE.txt file in the top level directory for more details.
-//
// Author: David Burken
//
// Description: Generic image writer class.
@@ -14,10 +12,14 @@
#define ossimWriter_HEADER 1
#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimIpt.h>
#include <ossim/imaging/ossimImageFileWriter.h>
#include <iosfwd>
#include <vector>
+class ossimKeywordlist;
+class ossimProperty;
+
/**
* @brief ossimWriter - Generic image writer.
*
@@ -101,6 +103,56 @@ public:
*/
virtual bool setOutputStream(std::ostream& str);
+ /**
+ * @brief Sets the output tile size for tiled formats.
+ * @param tileSize Must be a multiple of 16.
+ */
+ virtual void setTileSize(const ossimIpt& tileSize);
+
+ /**
+ * @brief Gets the tile size.
+ * @return Reference to tile size.
+ */
+ virtual const ossimIpt& getOutputTileSize() const;
+
+ /**
+ * @brief Saves the state of the object.
+ */
+ virtual bool saveState(ossimKeywordlist& kwl,
+ const char* prefix=0)const;
+
+ /**
+ * Method to the load (recreate) the state of an object from a keyword
+ * list. Return true if ok or false on error.
+ */
+ virtual bool loadState(const ossimKeywordlist& kwl,
+ const char* prefix=0);
+
+ /**
+ * Will set the property whose name matches the argument
+ * "property->getName()".
+ *
+ * @param property Object containing property to set.
+ */
+ virtual void setProperty(ossimRefPtr<ossimProperty> property);
+
+ /**
+ * @param name Name of property to return.
+ *
+ * @returns A pointer to a property object which matches "name". Returns
+ * NULL if no match is found.
+ */
+ virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name) const;
+
+ /**
+ * Pushes this's names onto the list of property names.
+ *
+ * @param propertyNames array to add this's property names to.
+ */
+ virtual void getPropertyNames(std::vector<ossimString>& propertyNames) const;
+
+
+
protected:
/**
@@ -110,7 +162,7 @@ protected:
virtual bool writeFile();
private:
-
+
/**
* @brief Writes a tiled tiff band separate to stream.
* @return true on success, false on error.
@@ -140,13 +192,9 @@ private:
* @brief Writes tags TIFFTAG_MINSAMPLEVALUE(280) and
* TIFFTAG_MAXSAMPLEVALUE(281). Only written if scalar type is an unsigned
* byte or short.
- * @param minBands Array of min values from image write.
- * @param maxBands Array of max values from image write.
* @return true on success, false on error.
*/
- bool writeMinMaxTiffTags( const std::vector<ossim_float64>& minBands,
- const std::vector<ossim_float64>& maxBands,
- std::streamoff& arrayWritePos );
+ bool writeMinMaxTiffTags( std::streamoff& arrayWritePos );
/**
@@ -155,7 +203,9 @@ private:
* unsigned byte or short.
* @param minBands Array of min values from image write.
* @param maxBands Array of max values from image write.
- * @return true on success, false on error.
+ * @return true if tags are written, false if not.
+ * A false return is not necessarily an error, just means the
+ * tags were not written due to the scalar type.
*/
bool writeSMinSMaxTiffTags( const std::vector<ossim_float64>& minBands,
const std::vector<ossim_float64>& maxBands,
@@ -199,9 +249,50 @@ private:
* @return TIFF sample format or 0 if not mapped to a scalar type.
*/
ossim_uint16 getTiffSampleFormat() const;
+
+ /**
+ * @return true if the output type is tiled, false if not.
+ */
+ bool isTiled() const;
+
+ /**
+ * @return Value of options key: "align_tiles".
+ * If true, aligns tile addresses to 4096 boundary.
+ * default=true
+ */
+ bool getAlignTilesFlag() const;
+
+ /**
+ * @return Value of options key: "flush_tiles".
+ * If true, aligns tile addresses to block boundary.
+ * default=true
+ */
+ ossim_int64 getBlockSize() const;
+
+ /**
+ * @return Value of options key: "flush_tiles".
+ * If true, ostream::flush() is called after each tile write.
+ * default=true
+ */
+ bool getFlushTilesFlag() const;
+
+ /**
+ * @return Value of options key: "include_blank_tiles".
+ * If true, empty/blank tiles will be written; if false, the tile will not
+ * be written, the tile offset and byte count will be set to zero.
+ * default=true (write blanks).
+ */
+ bool getWriteBlanksFlag() const;
+
+ bool needsMinMax() const;
std::ostream* m_str;
- bool m_ownsStreamFlag;
+ bool m_ownsStreamFlag;
+
+ /** Hold all options. */
+ ossimRefPtr<ossimKeywordlist> m_kwl;
+
+ ossimIpt m_outputTileSize;
}; // End: class ossimWriter
diff --git a/include/ossim/init/JsonConfig.h b/include/ossim/init/JsonConfig.h
new file mode 100644
index 0000000..f20e584
--- /dev/null
+++ b/include/ossim/init/JsonConfig.h
@@ -0,0 +1,184 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#pragma once
+
+#include <ostream>
+#include <ossim/plugin/ossimPluginConstants.h>
+#include <ossim/base/JsonInterface.h>
+#include <ossim/base/ossimFilename.h>
+#include <vector>
+#include <map>
+
+namespace ossim
+{
+// Forward decl defined after JsonParam
+class JsonParam;
+
+/**
+ * Base class for maintaining parameters affecting the runtime configuration of OSSIM executables.
+ * The state is imported and exported via JSON. There are default configuration files that should
+ * be part of the install, that are accessed by this class. Custom settings can also be loaded.
+ *
+ * There are two functionally equivalent forms for specifying parameters: long and short.
+ * Parameters are initially declared via the long form with descriptions and default values. These
+ * values must be supplied in default JSON files as part of the OSSIM install.
+ *
+ * Once the parameters are declared via the long form, the short form can be used to supply runtime
+ * overrides.
+ *
+ * The long form format is
+ *
+ * { "parameters": [
+ * {
+ * "name": "<param_name>",
+ * "descr": "<param description",
+ * "type": "string"|"float"|"uint"|"int"|"bool",
+ * "value": <value>
+ * }, ...
+ * ]
+ * }
+ *
+ * The short form is:
+ *
+ * { "parameters": [
+ * "<param_name>": <value>, ...
+ * ]
+ * }
+ *
+ * The short form parameter is only accepted if it has previously been loaded via the long form so
+ * that the data type is known.
+ *
+ * Parameters are usually accessed knowing the data type ahead of time. For example, a string
+ * parameter is accessed as:
+ *
+ * string paramVal = jsonConfig.getParameter("param_name").asSTring();
+ *
+ * If the parameter is not found, the special null-parameter is returned from getParameter(), and
+ * casting to a tye will return 0, false, or empty string.
+ */
+class OSSIM_DLL JsonConfig : public ossim::JsonInterface
+{
+public:
+ JsonConfig();
+
+ /** Default Ctor loads all default .json files in the share/ossim system dir */
+ JsonConfig(const ossimFilename& configFile);
+
+ //! Destructor
+ virtual ~JsonConfig();
+
+ //! Opens and parses JSON file. The "parameters" keyword is expected in the root node
+ bool open(const ossimFilename& configFile);
+
+ //! Reads the params controlling the process from the JSON node named "parameters".
+ virtual void loadJSON(const Json::Value& params_json_node);
+
+ //! Reads the params controlling the process from the JSON node named "parameters".
+ virtual void saveJSON(Json::Value& params_json_node) const;
+
+ //! Returns a parameter (might be a null parameter if paramName not found in the configuration.
+ JsonParam& getParameter(const char* paramName);
+
+ /** Adds parameter to the configuration. Any previous parameter of the same name is replaced. */
+ void setParameter(const JsonParam& p);
+
+ //! Convenience method returns TRUE if the currently set diagnostic level is <= level
+ bool diagnosticLevel(unsigned int level) const;
+
+ //! Outputs JSON to output stream provided.
+ friend std::ostream& operator<<(std::ostream& out, const JsonConfig& obj);
+
+ bool paramExists(const char* paramName) const;
+
+protected:
+ JsonConfig(const JsonConfig& /*hide_this*/) {}
+
+ bool getBoolValue(bool& rtn_val, const std::string& json_value) const;
+
+ std::map<std::string, JsonParam> m_paramsMap;
+ static JsonParam s_nullParam;
+};
+
+
+/**
+ * Represents a single configuration parameter. This class provides for packing and unpacking the
+ * parameter from JSON payload, and provides for handling all datatypes of parameters.
+ */
+class JsonParam
+{
+public:
+ enum ParamType {
+ UNASSIGNED=0,
+ BOOL=1,
+ INT=2,
+ UINT=3,
+ FLOAT=4,
+ STRING=5,
+ VECTOR=6
+ };
+
+ JsonParam() : _type(UNASSIGNED), _value(0) {}
+
+ JsonParam(const ossimString& argname,
+ const ossimString& arglabel,
+ const ossimString& argdescr,
+ ParamType argparamType,
+ void* value);
+
+ JsonParam(const JsonParam& copy);
+
+ ~JsonParam() { resetValue(); }
+
+ /** Initializes from a JSON node. Return true if successful */
+ bool loadJSON(const Json::Value& json_node);
+
+ void saveJSON(Json::Value& json_node) const;
+
+ const ossimString& name() const { return _name; }
+ const ossimString& label() const { return _label; }
+ const ossimString& descr() const { return _descr; }
+ ParamType type() const { return _type; }
+
+ bool isBool() const {return (_type == BOOL); }
+ bool asBool() const;
+
+ bool isUint() const {return (_type == UINT); }
+ unsigned int asUint() const;
+
+ bool isInt() const {return (_type == INT);}
+ int asInt() const;
+
+ bool isFloat() const {return (_type == FLOAT);}
+ double asFloat() const;
+
+ bool isString() const {return (_type == STRING);}
+ std::string asString() const;
+
+ bool isVector() const {return (_type == VECTOR);}
+ void asVector(std::vector<double>& v) const;
+
+ bool operator==(const JsonParam& p) const { return (p._name == _name); }
+
+ void setValue(const Json::Value& json_node);
+ void setValue(void* value);
+ void resetValue();
+
+ /** Outputs JSON to output stream provided */
+ friend std::ostream& operator<<(std::ostream& out, const JsonParam& obj);
+
+private:
+
+ ossimString _name;
+ ossimString _label;
+ ossimString _descr;
+ ParamType _type;
+ void* _value;
+};
+
+
+}
diff --git a/include/ossim/projection/ossimImageViewTransform.h b/include/ossim/projection/ossimImageViewTransform.h
index 393e61f..1f48d47 100644
--- a/include/ossim/projection/ossimImageViewTransform.h
+++ b/include/ossim/projection/ossimImageViewTransform.h
@@ -107,7 +107,13 @@ public:
virtual ossimDpt getRoundTripErrorImage(const ossimDpt& imagePt)const;
- virtual ossimDrect getImageToViewBounds(const ossimDrect& imageRect)const;
+ /** Computes the bounding rect in view space of the quad formed by the transformed image points
+ * of the input rect corners. */
+ virtual ossimDrect getImageToViewBounds(const ossimDrect& imageRect) const;
+
+ /** Computes the bounding rect in image space of the quad formed by the transformed view points
+ * of the input rect corners. */
+ virtual ossimDrect getViewToImageBounds(const ossimDrect& viewRect) const;
virtual bool loadState(const ossimKeywordlist& kwl,
const char* prefix =0);
diff --git a/include/ossim/projection/ossimRpcSolver.h b/include/ossim/projection/ossimRpcSolver.h
index 046efb5..b8456cd 100644
--- a/include/ossim/projection/ossimRpcSolver.h
+++ b/include/ossim/projection/ossimRpcSolver.h
@@ -8,6 +8,7 @@
#define ossimRpcSolver_HEADER
#include <vector>
+#include <ossim/base/ossimConstants.h>
#include <ossim/base/ossimRefPtr.h>
#include <ossim/base/ossimDpt.h>
#include <ossim/base/ossimGpt.h>
@@ -16,10 +17,8 @@
#include <ossim/matrix/newmat.h>
#include <ossim/projection/ossimRpcModel.h>
#include <ossim/projection/ossimRpcProjection.h>
-
-class ossimProjection;
-class ossimImageGeometry;
-class ossimNitfRegisteredTag;
+#include <ossim/support_data/ossimNitfRegisteredTag.h>
+#include <ossim/imaging/ossimImageGeometry.h>
/**
* This currently only support Rational poilynomial B format. This can be
diff --git a/include/ossim/projection/ossimSensorModel.h b/include/ossim/projection/ossimSensorModel.h
index 7360f9b..3ab2c62 100644
--- a/include/ossim/projection/ossimSensorModel.h
+++ b/include/ossim/projection/ossimSensorModel.h
@@ -253,7 +253,7 @@ public:
*/
virtual ossimSensorModel::CovMatStatus getObsCovMat(
const ossimDpt& ipos, NEWMAT::SymmetricMatrix& Cov,
- const ossim_float64 defPointingSigma = 0.5);
+ const ossim_float64 defPointingSigma = 0.5) const;
/**
* @brief Implementation of pure virtual
diff --git a/include/ossim/projection/ossimSensorModelTuple.h b/include/ossim/projection/ossimSensorModelTuple.h
index c386981..7d7a253 100644
--- a/include/ossim/projection/ossimSensorModelTuple.h
+++ b/include/ossim/projection/ossimSensorModelTuple.h
@@ -143,7 +143,7 @@ public:
void getRpcPqeInputs(ossimRpcPqeInputs& obj) const;
private:
- std::vector<ossimSensorModel*> theImages;
+ mutable std::vector<ossimRefPtr<ossimSensorModel> > theImages;
ossim_int32 theNumImages;
diff --git a/include/ossim/reg/GroundControlPoint.h b/include/ossim/reg/GroundControlPoint.h
new file mode 100644
index 0000000..505888a
--- /dev/null
+++ b/include/ossim/reg/GroundControlPoint.h
@@ -0,0 +1,83 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#ifndef GroundControlPoint_HEADER
+#define GroundControlPoint_HEADER 1
+
+#include <ossim/base/JsonInterface.h>
+#include <ossim/base/ossimEcefPoint.h>
+#include <ossim/matrix/newmat.h>
+#include <memory>
+
+namespace ossim
+{
+/**
+ * Class for representing a ground control point.
+ * TODO: mplement cross-correlation between GCPs
+ */
+class GroundControlPoint : public ossim::JsonInterface,
+ public std::enable_shared_from_this<GroundControlPoint>
+{
+public:
+
+ /**
+ * Creates new GCP from JSON object.
+ * The ground point (GCP) coordinates are specified in either ECF or geographic.
+ * The associated covariance must be in the same coordinate system. If correlations exist to
+ * other GCPs, those GCPs must share the same coordinate system. TBD: Perhaps the GCP
+ * information, including coordinates, covariances and cross-covariances can be ingested prior
+ * and accessed from the database with only GCP ID. Id so, the remainder of this message is not
+ * needed.
+ *
+ * The JSON Format:
+ * {
+ * "id": <string>,
+ * "ecf": [ <X>, <Y>, <Z> ], OR
+ * "geo": [ <lat>, <lon>, <hgt_msl> ],
+ * "covariance": [ c11, c22, c33, c12, c13, c23 ],
+ * "crossCovariances": [ (Can be excluded if no correlation information available)
+ * {
+ * "id": <string>, The other GCP’s ID
+ * "crossCovariance": [ c11, c22, c33, c12, c13, c23 ]
+ * }
+ * ]
+ * }
+ *
+ */
+ GroundControlPoint(const Json::Value& image_json_node);
+
+ virtual ~GroundControlPoint();
+
+ const std::string& getId() const { return m_id; }
+ const ossimEcefPoint& getECF() const { return m_gcp; }
+
+ const NEWMAT::SymmetricMatrix& getCovariance() const {return m_covariance;}
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void loadJSON(const Json::Value& json);
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void saveJSON(Json::Value& json) const;
+
+private:
+ GroundControlPoint();
+
+ std::string m_id;
+ ossimEcefPoint m_gcp;
+ NEWMAT::SymmetricMatrix m_covariance; //> X, Y, Z (ECF)
+};
+
+typedef std::vector< std::shared_ptr<GroundControlPoint> > GcpList;
+
+} // end namespace ossimMsp
+#endif /* #ifndef GroundControlPoint_HEADER */
diff --git a/include/ossim/reg/Image.h b/include/ossim/reg/Image.h
new file mode 100644
index 0000000..0de6d12
--- /dev/null
+++ b/include/ossim/reg/Image.h
@@ -0,0 +1,85 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+#ifndef Image_HEADER
+#define Image_HEADER 1
+
+#include <map>
+#include <memory>
+#include <string>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/matrix/newmat.h>
+#include <ossim/base/JsonInterface.h>
+#include <ossim/projection/ossimSensorModel.h>
+#include <string>
+
+namespace ossim
+{
+
+/**
+ * Class representing an Image as used by ossim-msp services.
+ */
+class OSSIM_DLL Image : public ossim::JsonInterface,
+ public std::enable_shared_from_this<Image>
+{
+public:
+ static unsigned int UNASSIGNED_PHOTOBLOCK_INDEX;
+
+ Image(const std::string& imageId,
+ const std::string& filename,
+ const std::string& modelName="",
+ unsigned int entryIndex=0,
+ unsigned int band=1);
+
+ Image(const Json::Value& image_json_node);
+
+ ~Image();
+
+ std::string getImageId() const { return m_imageId; }
+ std::string getFilename() const { return m_filename; }
+ std::string getModelName() const { return m_modelName; }
+ unsigned int getEntryIndex() const { return m_entryIndex; }
+ unsigned int getActiveBand() const { return m_activeBand; }
+
+ void setImageId(const std::string& id) { m_imageId = id; }
+ void setFilename(const std::string& f) { m_filename = f; }
+ void setEntryIndex(unsigned int i) { m_entryIndex = i; }
+
+ /**
+ * Returns all available sensor model plugins and model names for this image:
+ * @param availableModels List of <plugin-name, model-name> pairs.
+ */
+ virtual void getAvailableModels(std::vector< pair<std::string, std::string> >& availableModels) const;
+
+ /**
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void loadJSON(const Json::Value& json);
+
+ /**
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void saveJSON(Json::Value& json) const;
+
+protected:
+ std::string m_imageId;
+ ossimFilename m_filename;
+ unsigned int m_entryIndex;
+ unsigned int m_activeBand;
+ std::string m_modelName;
+ std::vector< pair<std::string, std::string> > m_availableModel;
+ ossimRefPtr<ossimSensorModel> m_sensorModel;
+};
+
+typedef std::vector< std::shared_ptr<Image> > ImageList;
+
+} // End namespace ATP
+
+#endif
diff --git a/include/ossim/reg/PhotoBlock.h b/include/ossim/reg/PhotoBlock.h
new file mode 100644
index 0000000..9ab0fbd
--- /dev/null
+++ b/include/ossim/reg/PhotoBlock.h
@@ -0,0 +1,99 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+#ifndef PhotoBlock_HEADER
+#define PhotoBlock_HEADER 1
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/reg/GroundControlPoint.h>
+#include <ossim/reg/Image.h>
+#include <ossim/reg/TiePoint.h>
+#include <ossim/base/JsonInterface.h>
+
+namespace ossim
+{
+
+/**
+ * Class for representing MSP PhotoBlock.
+ */
+class PhotoBlock : public JsonInterface,
+ public std::enable_shared_from_this<PhotoBlock>
+{
+public:
+ /**
+ * Initialize the photoblock from a prior saved session. If none found, assumes a new, blank
+ * session is being started.
+ */
+ PhotoBlock();
+ PhotoBlock(const Json::Value& pb_json_node);
+ PhotoBlock(const PhotoBlock& copyThis);
+
+ ~PhotoBlock();
+
+ PhotoBlock& operator=(const PhotoBlock& copythis);
+
+ std::shared_ptr<Image> getImage(const std::string& imageId);
+ std::shared_ptr<TiePoint> getTiePoint(unsigned int tpId);
+ std::shared_ptr<GroundControlPoint> getGroundPoint(const std::string& gpId);
+
+ ImageList& getImageList() { return m_imageList; }
+ TiePointList& getTiePointList() { return m_tiePointList; }
+ std::vector<std::shared_ptr<GroundControlPoint> >& getGroundPointList() { return m_gcpList; }
+
+ // TODO: Add of individual components not valid until proper management of the JCM can be
+ // provided
+
+ /**
+ * Adds the image to the photoblock at last position. Sets the image's pb index member.
+ * @param images To be added to PB
+ * @return The PB index of the image in the photoblock.
+ */
+ unsigned int addImage(std::shared_ptr<Image> image);
+
+ /**
+ * Adds the image to the photoblock at last position. Sets the image's pb index member.
+ * @param images To be added to PB
+ * @return The PB index of the image in the photoblock.
+ */
+ unsigned int addGroundPoint(std::shared_ptr<GroundControlPoint> groundPoint);
+
+ /**
+ * Adds the tiepoint to the PB
+ * @param tiepoint To be added to PB
+ * @return The index of the TP in the photoblock (should be same as TP ID)
+ */
+ unsigned int addTiePoint(std::shared_ptr<TiePoint> tiepoint);
+
+ /**
+ * Adds the list of tiepoints to the PB
+ * @param tiepointList To be added to PB
+ */
+ void addTiePoints(TiePointList& tiepointList);
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void loadJSON(const Json::Value& json);
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void saveJSON(Json::Value& json) const;
+
+protected:
+ std::vector<std::shared_ptr<Image> > m_imageList;
+ std::vector<std::shared_ptr<TiePoint> > m_tiePointList;
+ std::vector<std::shared_ptr<GroundControlPoint> > m_gcpList;
+};
+
+} // End namespace ISA
+
+#endif
diff --git a/include/ossim/reg/TiePoint.h b/include/ossim/reg/TiePoint.h
new file mode 100644
index 0000000..2fc5ba4
--- /dev/null
+++ b/include/ossim/reg/TiePoint.h
@@ -0,0 +1,126 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#ifndef TiePoint_HEADER
+#define TiePoint_HEADER 1
+
+#include <ossim/base/JsonInterface.h>
+#include <ossim/reg/Image.h>
+#include <ossim/base/ossimDpt.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/matrix/newmat.h>
+#include <vector>
+#include <memory>
+
+namespace ossim
+{
+class TiePoint;
+typedef std::vector< std::shared_ptr<TiePoint> > TiePointList;
+
+/**
+ * Class for representing a single tiepoint on two or more images. It also represents image-points
+ * associated with a ground control point.
+ */
+class TiePoint : public ossim::JsonInterface,
+ public std::enable_shared_from_this<TiePoint>
+{
+public:
+ enum Type {
+ UNASSIGNED,
+ MANUAL, //> The point was created or edited manually and contains at least a pair of image points
+ AUTO, //> Result of auto tie point generation and contains at least a pair of image points
+ GCP //> point is associated with a manually-entered ground control. Possibly multiple image points
+ };
+
+ TiePoint();
+
+ TiePoint(const TiePoint& copy);
+
+ /**
+ * Creates new tiepoint from JSON object formatted as:
+ * {
+ * "id": <unsigned int>, // may be ignored if not valid
+ * "type": "M"|"A"|"G" For “manual”, “auto”, or “GCP-associated”
+ * "imagePoints: [
+ * {
+ * "imageId": <string>,
+ * "x": <double>,
+ * "y": <double>,
+ * "covariance": [ cxx, cyy, cxy ],
+ * "gcpId": <string> Only if associated with a GCP
+ * }
+ * ]
+ * }
+ */
+ TiePoint(const Json::Value& tp_json_node);
+
+ virtual ~TiePoint();
+
+ unsigned int getImageCount() const { return m_images.size(); }
+
+ const std::string& getTiePointId() const { return m_tiePointId; }
+
+ void setTiePointId(const std::string& id);
+
+ /**
+ * Fetches the image point coordinates along with image ID and GCP ID if available.
+ * @param index Inout index into the list of images containing this tiepoint
+ * @param imageId Output image ID for the ccorresponding image point
+ * @param imagePoint image coordinates
+ * @param cov image point measurement covariance in (x, y) coordinates
+ */
+ void getImagePoint(unsigned int index,
+ std::string& imageId,
+ ossimDpt& imagePoint,
+ NEWMAT::SymmetricMatrix& cov) const;
+
+ /**
+ * Sets image point value and associated measurement covariance for specified image ID.
+ * If the image ID is not found, it will be added as new observation.
+ */
+ void setImagePoint(std::shared_ptr<Image> image,
+ const ossimDpt& imagePoint,
+ const NEWMAT::SymmetricMatrix& cov);
+
+ Type getType() const { return m_type; }
+ void setType(Type t) { m_type = t; }
+
+ const std::string& getGcpId() const { return m_gcpId; }
+ void setGcpId(const std::string& id);
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void loadJSON(const Json::Value& json);
+
+ /*
+ * Refer to <a href="https://docs.google.com/document/d/1DXekmYm7wyo-uveM7mEu80Q7hQv40fYbtwZq-g0uKBs/edit?usp=sharing">3DISA API document</a>
+ * for JSON format used.
+ */
+ virtual void saveJSON(Json::Value& json) const;
+
+ virtual std::ostream& print(std::ostream& out) const;
+ friend std::ostream& operator << (std::ostream& out, const TiePoint& tp)
+ { return tp.print(out); }
+
+protected:
+
+ Type m_type;
+ std::string m_tiePointId;
+ std::vector< std::shared_ptr<Image> > m_images; //> List of images containing common feature
+ std::vector<ossimDpt> m_imagePoints; //> List of image point measurements for common feature
+ std::vector<NEWMAT::SymmetricMatrix> m_covariances; //> List of measurement covariances corresponding to image points vector
+ double m_gsd; //> image scale (meters/pixel) at which matching was performed
+ std::string m_gcpId; //> Cross reference to GCP record associated with this TP.
+ static int s_runningId;
+};
+
+typedef std::vector< std::shared_ptr<TiePoint> > TiePointList;
+
+} // end namespace ATP
+#endif /* #ifndef TiePoint_HEADER */
diff --git a/include/ossim/util/ossimTool.h b/include/ossim/util/ossimTool.h
index 19c020e..9626fc4 100644
--- a/include/ossim/util/ossimTool.h
+++ b/include/ossim/util/ossimTool.h
@@ -12,13 +12,15 @@
#include <ossim/base/ossimObject.h>
#include <ossim/base/ossimArgumentParser.h>
#include <ossim/base/ossimKeywordlist.h>
+#include <ossim/base/JsonInterface.h>
#include <iostream>
/*!
* Base class for all OSSIM tool applications. These are utilities providing high-level
* functionality via the OSSIM library.
*/
-class OSSIM_DLL ossimTool : public ossimObject
+class OSSIM_DLL ossimTool : public ossimObject, public ossim::JsonInterface
+
{
public:
ossimTool();
@@ -43,12 +45,18 @@ public:
virtual void initialize(const ossimKeywordlist& kwl);
/**
- * Reads processing params from string provided (usually JSON-formatted, though that's up to the
- * derived class to implement and contract with consumer). If all good, the object is ready for
+ * Reads processing params from JSON object provided. If all good, the object is ready for
* subsequent call to execute().
* @note Throws ossimException on error.
*/
- virtual void initialize(const std::string& request);
+ virtual void loadJSON(const Json::Value& json_request) {};
+
+ /**
+ * Fetch product as JSON object when applicable
+ * Always returns true since using exception on error.
+ * @param json Returns non-empty object if valid response available.
+ */
+ virtual void saveJSON(Json::Value& json) const { json.clear(); }
/**
* Writes product to output file if applicable. The product may also beAlways returns true since using exception on error.
diff --git a/scripts/archive.sh b/scripts/archive.sh
index cf2b38c..e6e5d3e 100755
--- a/scripts/archive.sh
+++ b/scripts/archive.sh
@@ -7,7 +7,7 @@
# This script will create a tarball, e.g. ossim-1.9.0.tar.gz
# from a the top level set of ossim git modules, i.e. ossim_labs_dev_root.
#---
-pushd `dirname $0` >/dev/null
+pushd `dirname ${BASH_SOURCE[0]}` >/dev/null
export SCRIPT_DIR=$PWD
popd >/dev/null
pushd $SCRIPT_DIR/../.. > /dev/null
diff --git a/scripts/build.sh b/scripts/build.sh
index 1284d7d..b6108cd 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -23,13 +23,8 @@
# Uncomment following line to debug script line by line:
#set -x; trap read debug
-# Working directory must be top-level dir:
-#SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-#pushd $SCRIPT_DIR/../..
-#OSSIM_DEV_HOME=$PWD
-
#CMAKE_CONFIG_SCRIPT=$OSSIM_DEV_HOME/ossim/cmake/scripts/ossim-cmake-config.sh
-pushd `dirname $0` >/dev/null
+pushd `dirname ${BASH_SOURCE[0]}` >/dev/null
export SCRIPT_DIR=`pwd -P`
popd >/dev/null
# source variables used during the builds
diff --git a/scripts/env.sh b/scripts/env.sh
index 1d2da86..bb0b628 100755
--- a/scripts/env.sh
+++ b/scripts/env.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-pushd `dirname $0` >/dev/null
+pushd `dirname ${BASH_SOURCE[0]}` >/dev/null
export SCRIPT_DIR=`pwd -P`
popd >/dev/null
diff --git a/scripts/install.sh b/scripts/install.sh
index cdea747..048bc9e 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-pushd `dirname $0` >/dev/null
+pushd `dirname ${BASH_SOURCE[0]}` >/dev/null
export SCRIPT_DIR=`pwd -P`
popd >/dev/null
# source variables used during the builds
diff --git a/share/ossim/templates/ossim_preferences_template b/share/ossim/templates/ossim_preferences_template
index 68ab95e..ee95c24 100644
--- a/share/ossim/templates/ossim_preferences_template
+++ b/share/ossim/templates/ossim_preferences_template
@@ -355,7 +355,10 @@ plugin5.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_kakadu_plugi
plugin15.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_mrsid_plugin.so
// plugin15 .options:
-plugin16.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_isa_plugin.so
+plugin16.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_msp_plugin.so
+// plugin15 .options:
+
+plugin17.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_atp_plugin.so
// plugin15 .options:
plugin20.file: $(OSSIM_INSTALL_PREFIX)/lib64/ossim/plugins/libossim_cnes_plugin.so
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5d92e33..b21972e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,6 +4,7 @@ FILE(GLOB ossim_SRCS RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/ossimConfig*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ossimVer*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/init/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/reg/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/reg/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/base/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/base/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/elevation/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/elevation/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/font/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/font/*.c"
@@ -13,6 +14,7 @@ FILE(GLOB ossim_SRCS RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/point_cloud/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/point_cloud/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/projection/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/projection/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/support_data/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/support_data/*.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/reg/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/reg/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/util/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/util/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/vec/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/vec/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/video/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/video/*.c"
@@ -49,6 +51,7 @@ FILE(GLOB ossim_elevation_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_C
FILE(GLOB ossim_font_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/font/*.h")
FILE(GLOB ossim_imaging_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/imaging/*.h")
FILE(GLOB ossim_init_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/init/*.h")
+FILE(GLOB ossim_reg_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/reg/*.h")
FILE(GLOB ossim_matrix_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/matrix/*.h")
FILE(GLOB ossim_parallel_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/parallel/*.h")
FILE(GLOB ossim_plugin_HDRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../include/ossim/plugin/*.h")
@@ -72,7 +75,7 @@ MESSAGE( "${ossim_HDRS}" )
SET(OSSIM_HEADER_FILES
${ossim_HDRS}
${ossim_base_HDRS} ${ossim_elevation_HDRS} ${ossim_font_HDRS} ${ossim_imaging_HDRS}
- ${ossim_init_HDRS} ${ossim_matrix_HDRS} ${ossim_parallel_HDRS} ${ossim_plugin_HDRS}
+ ${ossim_init_HDRS} ${ossim_reg_HDRS} ${ossim_matrix_HDRS} ${ossim_parallel_HDRS} ${ossim_plugin_HDRS}
${ossim_point_cloud_HDRS} ${ossim_projection_HDRS} ${ossim_support_data_HDRS} ${ossim_util_HDRS}
${ossim_vec_HDRS} ${ossim_video_HDRS} ${ossim_vpfutil_HDRS} ${ossim_sockets_HDRS} ${ossim_hdf5_HDRS} )
@@ -97,6 +100,9 @@ IF(APPLE)
FOREACH(f ${ossim_init_HDRS} )
SET_SOURCE_FILES_PROPERTIES( ${f} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/init )
ENDFOREACH(f)
+ FOREACH(f ${ossim_reg_HDRS} )
+ SET_SOURCE_FILES_PROPERTIES( ${f} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/reg )
+ ENDFOREACH(f)
FOREACH(f ${ossim_matrix_HDRS} )
SET_SOURCE_FILES_PROPERTIES( ${f} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/matrix )
ENDFOREACH(f)
@@ -158,6 +164,7 @@ IF(NOT OSSIM_BUILD_FRAMEWORKS OR NOT APPLE)
install(FILES ${ossim_font_HDRS} DESTINATION include/ossim/font COMPONENT ossim)
install(FILES ${ossim_imaging_HDRS} DESTINATION include/ossim/imaging COMPONENT ossim)
install(FILES ${ossim_init_HDRS} DESTINATION include/ossim/init COMPONENT ossim)
+ install(FILES ${ossim_reg_HDRS} DESTINATION include/ossim/reg COMPONENT ossim)
install(FILES ${ossim_matrix_HDRS} DESTINATION include/ossim/matrix COMPONENT ossim)
install(FILES ${ossim_parallel_HDRS} DESTINATION include/ossim/parallel COMPONENT ossim)
install(FILES ${ossim_plugin_HDRS} DESTINATION include/ossim/plugin COMPONENT ossim)
diff --git a/src/base/ossimKeywordlist.cpp b/src/base/ossimKeywordlist.cpp
index 4a343dc..2e7b806 100755
--- a/src/base/ossimKeywordlist.cpp
+++ b/src/base/ossimKeywordlist.cpp
@@ -13,17 +13,19 @@
#include <ossim/base/ossimIoStream.h>
#include <ossim/base/ossimNotify.h>
+#include <ossim/base/ossimRefPtr.h>
#include <ossim/base/ossimRegExp.h>
+#include <ossim/base/ossimStreamFactoryRegistry.h>
#include <ossim/base/ossimTrace.h>
+#include <ossim/base/ossimXmlNode.h>
#include <algorithm>
#include <fstream>
#include <list>
+#include <memory>
#include <sstream>
#include <utility>
-#include <cstddef> // nullptr
-#include <ossim/base/BlockIStream.h>
#include <ossim/base/ossimStreamFactoryRegistry.h>
static ossimTrace traceDebug("ossimKeywordlist:debug");
@@ -728,16 +730,15 @@ bool ossimKeywordlist::parseFile(const ossimFilename& file,
{
bool result = false;
- std::shared_ptr<ossim::ifstream> is = std::make_shared<ossim::ifstream>(file.c_str(),
- std::ios::in | std::ios::binary);
- if(is&&is->is_open())
+ std::shared_ptr<ossim::istream> is = ossim::StreamFactoryRegistry::instance()->
+ createIstream( file.string() );
+ if ( is )
{
- std::shared_ptr<ossim::BlockIStream> blockedStream = std::make_shared<ossim::BlockIStream>(is, 4096);
m_currentlyParsing = file;
result = parseStream(*is, ignoreBinaryChars);
+ is.reset();
}
-
- is = nullptr;
+
return result;
}
@@ -1094,7 +1095,7 @@ void ossimKeywordlist::getSortedList(std::vector<ossimString>& prefixValues,
ossim_uint32 offset = (int)ossimString(prefixKey).size();
ossim_uint32 idx = 0;
std::vector<ossim_uint32> numberList(nKeys);
- for(idx = 0; idx < (int)numberList.size();++idx)
+ for(idx = 0; idx < (ossim_uint32)numberList.size();++idx)
{
ossimString numberStr(keys[idx].begin() + offset,
keys[idx].end());
@@ -1102,7 +1103,7 @@ void ossimKeywordlist::getSortedList(std::vector<ossimString>& prefixValues,
}
std::sort(numberList.begin(), numberList.end());
- for(idx=0;idx < (int)numberList.size();++idx)
+ for(idx=0;idx < (ossim_uint32)numberList.size();++idx)
{
prefixValues.push_back(prefixKey+ossimString::toString(numberList[idx]));
}
@@ -1473,3 +1474,407 @@ bool ossimKeywordlist::getBoolKeywordValue(bool& rtn_val,
return found;
}
+bool ossimKeywordlist::isSpecialXmlCharacters(const ossimString& value)const
+{
+ for(ossimString::const_iterator it = value.begin(); it != value.end();++it)
+ {
+ switch(*it)
+ {
+ case '&':
+ case '<':
+ case '>':
+ case '"':
+ case '\'':
+ {
+ return true;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ }
+ return false;
+}
+
+bool ossimKeywordlist::isValidTag(const std::string& value)const
+{
+ std::string::const_iterator textChars = value.begin();
+ bool result = true;
+ if(!isalpha(*(textChars) ))
+ {
+ result = false;
+ }
+ else if(!value.empty())
+ {
+ for(++textChars;textChars!=value.end();++textChars)
+ {
+ if(!isalnum(*(textChars) ))
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ result = false;
+ }
+
+ return result;
+}
+
+void ossimKeywordlist::replaceSpecialCharacters(ossimString& value)const
+{
+ ossimString::iterator iter = value.begin();
+
+ while(iter!=value.end())
+ {
+ if(!(isdigit(*iter) ||
+ isalpha(*iter)||
+ (*iter=='/')))
+ {
+ *iter = '_';
+ }
+ ++iter;
+ }
+}
+
+void ossimKeywordlist::toXML(std::ostream& out, const std::string& rootTag)const
+{
+ std::string rootTagStr = rootTag;
+ if (!isValidTag(rootTagStr))
+ {
+ rootTagStr = "info";
+ }
+
+ ossimRefPtr<ossimXmlNode> metadata = new ossimXmlNode;
+ metadata->setTag("metadata");
+ ossimKeywordlist::KeywordMap::const_iterator iter = m_map.begin();
+ while(iter != m_map.end())
+ {
+ ossimString path = iter->first;
+ bool outputValue = true;
+ ossimString value = iter->second;
+ if(path.contains("unformatted_tag_data"))
+ {
+ ossimString temp = value.trim();
+ if(ossimString(temp.begin(), temp.begin()+5) == "<?xml")
+ {
+ value = "XML not converted";
+ outputValue = false;
+ }
+ }
+
+ if(outputValue)
+ {
+ bool tagOk = true;
+ path = path.substitute(".", "/", true);
+ replaceSpecialCharacters(path);
+ std::vector<ossimString> splitValues;
+ path.split(splitValues,"/");
+ if(splitValues.size())
+ {
+ splitValues[splitValues.size()-1] = splitValues[splitValues.size()-1].downcase();
+ ossim_uint32 idx = 0;
+ for(idx = 0; ((idx < splitValues.size()-1)&&tagOk);++idx)
+ {
+ if(!isValidTag(splitValues[idx]))
+ {
+ tagOk = false;
+ }
+ splitValues[idx] = splitValues[idx].upcase();
+ }
+ }
+ if(tagOk)
+ {
+ path.join(splitValues, "/");
+ ossimRefPtr<ossimXmlNode> node = metadata->addNode(path.c_str(), value);
+ if(isSpecialXmlCharacters(value))
+ {
+ node->setCDataFlag(true);
+ }
+ }
+ }
+ ++iter;
+ }
+
+ if( 1 ) // tmp dbr !m_includeMetadataTagName)
+ {
+ out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
+ << "<" << rootTagStr << ">\n";
+
+ const ossimXmlNode::ChildListType& children = metadata->getChildNodes();
+ ossimXmlNode::ChildListType::const_iterator iter = children.begin();
+ while(iter != children.end())
+ {
+ out << *(iter->get());
+ ++iter;
+ }
+ out << "\n</" << rootTagStr << ">" << std::endl;
+ }
+ else
+ {
+ out << *(metadata.get()) << std::endl;
+ }
+}
+
+
+void ossimKeywordlist::toJSON(std::ostream& out, const std::string& rootTag)const
+{
+ const std::string C = ": "; // colon
+ const std::string DQ = "\""; // double Quote
+ const std::string LB = "{"; // left bracket
+ const std::string CNL = ",\n"; // coma, new line
+ const std::string NL = "\n"; // new line
+ const std::string RB = "}"; // left bracket
+ const std::string S = " "; // space
+ ossim_uint32 nameCount = 0;
+ ossimString lastObject;
+ ossim_uint32 indentCount = 3;
+ ossim_uint32 indentOffset = 3;
+
+ bool stringify = true;
+ bool closeObject = false;
+ std::vector<ossimString> objectStack;
+
+ // Opening bracket:
+ out << LB;
+
+ if( rootTag.size() )
+ {
+ if ( stringify )
+ {
+ indentOffset = indentCount;
+ std::string indent(indentCount, ' ');
+ out << NL << indent;
+ }
+ else
+ {
+ out << NL;
+ }
+ // Note: not adding rootTag to object stack
+ out << DQ << rootTag << DQ << C << LB << NL;
+ }
+
+ ossimKeywordlist::KeywordMap::const_iterator iter = m_map.begin();
+ while(iter != m_map.end())
+ {
+ bool outputValue = true;
+ ossimString key = iter->first;
+ ossimString value = iter->second;
+ value = value.trim(); // remove spaces
+
+#if 0
+ if(key.contains("unformatted_tag_data"))
+ {
+ ossimString temp = value.trim();
+ if(ossimString(temp.begin(), temp.begin()+5) == "<?xml")
+ {
+ value = "data not converted";
+ outputValue = false;
+ }
+ }
+#endif
+
+ if ( outputValue && key.size() )
+ {
+ std::vector<ossimString> keys;
+ key.split(keys,".");
+
+ if ( keys.size() )
+ {
+ // The last key is the name so grab it now and pop it off the stack:
+ ossimString name = keys[keys.size()-1];
+ keys.pop_back();
+
+ bool sameObject = isSame( keys, objectStack );
+ if ( !sameObject && keys.size() )
+ {
+ for ( ossim_uint32 i = 0; i < keys.size(); ++i )
+ {
+ if ( i < objectStack.size() )
+ {
+ if ( keys[i] == objectStack[i] )
+ {
+ // On stack already. Nothng to do. Go to next key.
+ continue;
+ }
+ else
+ {
+ // Different object:
+ while ( i < objectStack.size() )
+ {
+ // Write bracket, then pop:
+ if ( stringify )
+ {
+ std::string indent(indentOffset+(indentCount*objectStack.size()), ' ');
+ out << NL << indent << RB;
+ }
+ else
+ {
+ out << NL << RB;
+ }
+ objectStack.pop_back();
+ nameCount = 0;
+ closeObject = true;
+ if ( objectStack.size() )
+ {
+ lastObject = objectStack[objectStack.size()-1];
+ }
+ else
+ {
+ lastObject.clear();
+ }
+ }
+ }
+ }
+
+ //---
+ // New object:
+ // If we had written a key:value for previos object, do a
+ // newline and zero it out.
+ //---
+ if ( nameCount )
+ {
+ out << CNL;
+ nameCount = 0;
+ }
+
+ objectStack.push_back( keys[i] );
+
+ if ( closeObject )
+ {
+ out << CNL;
+ closeObject = false;
+ }
+
+ if ( stringify )
+ {
+ std::string indent(indentOffset+(indentCount*objectStack.size()), ' ');
+ out << indent;
+ }
+ out << DQ << keys[i] << DQ << C << LB << NL;
+ }
+
+ // Final check if keys shrunk, pop objects off the object stack.
+ while ( keys.size() < objectStack.size() )
+ {
+ // Write bracket then pop:
+ if ( stringify )
+ {
+ std::string indent(indentOffset+(indentCount*objectStack.size()), ' ');
+ out << NL << indent << RB;
+ }
+ else
+ {
+ out << NL << RB;
+ }
+ objectStack.pop_back();
+ nameCount = 0;
+ closeObject = true;
+ if ( objectStack.size() )
+ {
+ lastObject = objectStack[objectStack.size()-1];
+ }
+ else
+ {
+ lastObject.clear();
+ }
+ }
+ }
+
+ if ( objectStack.size() )
+ {
+ if ( lastObject == objectStack[objectStack.size()-1] )
+ {
+ out << CNL;
+ closeObject = false;
+ }
+ }
+ else if ( nameCount ) // No objects loaded on the stack.
+ {
+ out << CNL;
+ }
+
+ // Output "key": "value"
+ if ( stringify )
+ {
+ std::string indent(indentOffset+indentCount*(objectStack.size()+1), ' ');
+ out << indent;
+ }
+ out << DQ << name << DQ << C << DQ << value << DQ;
+
+ if ( objectStack.size() )
+ {
+ lastObject = objectStack[objectStack.size()-1];
+ }
+ else
+ {
+ lastObject.clear();
+ }
+
+ ++nameCount;
+ }
+ }
+ ++iter;
+
+ } // Matches: while(iter != m_map.end())
+
+ // Close out brackets:
+ ossim_uint32 stackSize = objectStack.size();
+ if ( stackSize )
+ {
+ for ( ossim_uint32 i = stackSize; i > 0; --i )
+ {
+ if ( stringify )
+ {
+ std::string indent(indentOffset+indentCount*i, ' ');
+ out << NL << indent << RB;
+ }
+ else
+ {
+ out << NL << RB;
+ }
+ }
+ }
+
+ if( rootTag.size() )
+ {
+ if ( stringify )
+ {
+ std::string indent(indentCount, ' ');
+ out << NL << indent << RB;
+ }
+ else
+ {
+ out << NL << RB;
+ }
+ }
+
+ // Closing bracket, newline with flush:
+ out << NL << RB << std::endl;
+}
+
+bool ossimKeywordlist::isSame( const std::vector<ossimString>& a,
+ const std::vector<ossimString>& b ) const
+{
+ bool result = true;
+ if ( a.size() == b.size() )
+ {
+ for ( ossim_uint32 i = 0; i < a.size(); ++i )
+ {
+ if ( a[i] != b[i] )
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ result = false;
+ }
+ return result;
+}
diff --git a/src/imaging/ossimImageRenderer.cpp b/src/imaging/ossimImageRenderer.cpp
index 92e1fc4..187cdd6 100644
--- a/src/imaging/ossimImageRenderer.cpp
+++ b/src/imaging/ossimImageRenderer.cpp
@@ -1873,19 +1873,26 @@ void ossimImageRenderer::getValidImageVertices(vector<ossimIpt>& validVertices,
//*************************************************************************************************
ossimRefPtr<ossimImageGeometry> ossimImageRenderer::getImageGeometry()
{
- // Make sure the IVT was properly initialized
- if (m_ImageViewTransform.valid() && !m_ImageViewTransform->isValid())
- checkIVT();
+ ossimRefPtr<ossimImageGeometry> geom = 0;
+ if (isSourceEnabled())
+ {
+ // Make sure the IVT was properly initialized
+ if (m_ImageViewTransform.valid() && !m_ImageViewTransform->isValid())
+ checkIVT();
- ossimImageViewProjectionTransform* ivpt =
- dynamic_cast<ossimImageViewProjectionTransform*>(m_ImageViewTransform.get());
- if (ivpt)
+ ossimImageViewProjectionTransform* ivpt =
+ dynamic_cast<ossimImageViewProjectionTransform*>(m_ImageViewTransform.get());
+ if (ivpt)
+ {
+ // we need to return the right side since the geometry changed to a view geometry
+ geom = ivpt->getViewGeometry();
+ }
+ }
+ else if (theInputConnection)
{
- // we need to return the right side since the geometry changed to a view geometry
- return ivpt->getViewGeometry();
+ geom = theInputConnection->getImageGeometry();
}
-
- return ossimRefPtr<ossimImageGeometry>();
+ return geom;
}
void ossimImageRenderer::connectInputEvent(ossimConnectionEvent& /* event */)
diff --git a/src/imaging/ossimImageWriterFactory.cpp b/src/imaging/ossimImageWriterFactory.cpp
index 2a00960..d555e56 100644
--- a/src/imaging/ossimImageWriterFactory.cpp
+++ b/src/imaging/ossimImageWriterFactory.cpp
@@ -8,7 +8,7 @@
// Author: Garrett Potts
//
//*******************************************************************
-// $Id: ossimImageWriterFactory.cpp 22242 2013-04-20 02:16:06Z gpotts $
+// $Id$
#include <ossim/imaging/ossimImageWriterFactory.h>
#include <ossim/base/ossimImageTypeLut.h>
@@ -148,7 +148,6 @@ ossimImageWriterFactory::createWriter(const ossimString& typeName)const
}
writer = new ossimTiffWriter;
-
if (STATIC_TYPE_NAME(ossimTiffWriter) == typeName )
{
return writer.release();
@@ -321,7 +320,7 @@ void ossimImageWriterFactory::getTypeNameList(std::vector<ossimString>& typeList
typeList.push_back(STATIC_TYPE_NAME(ossimNitfWriter));
typeList.push_back(STATIC_TYPE_NAME(ossimNitf20Writer));
typeList.push_back(STATIC_TYPE_NAME(ossimPdfWriter));
- typeList.push_back(STATIC_TYPE_NAME(ossimWriter));
+ typeList.push_back(ossimString("ossimWriter"));
}
void ossimImageWriterFactory::getImageFileWritersBySuffix(
diff --git a/src/imaging/ossimWriter.cpp b/src/imaging/ossimWriter.cpp
index d7a1d82..0539ac9 100644
--- a/src/imaging/ossimWriter.cpp
+++ b/src/imaging/ossimWriter.cpp
@@ -10,7 +10,11 @@
// $Id$
#include <ossim/imaging/ossimWriter.h>
+#include <ossim/base/ossimBooleanProperty.h>
#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimKeywordNames.h>
+#include <ossim/base/ossimProperty.h>
+#include <ossim/base/ossimStringProperty.h>
#include <ossim/base/ossimRefPtr.h>
#include <ossim/base/ossimTiffConstants.h>
#include <ossim/base/ossimTrace.h>
@@ -21,20 +25,38 @@
#include <limits>
#include <ostream>
-static const ossimTrace traceDebug("ossimWriter:debug");
+static const std::string ALIGN_TILES_KW = "align_tiles"; // bool
+static const std::string BLOCK_SIZE_KW = "block_size"; // unsigned int
+static const std::string FLUSH_TILES_KW = "flush_tiles"; // bool
+static const std::string INCLUDE_BLANK_TILES_KW = "include_blank_tiles"; // bool
+static const std::string TILE_SIZE_KW = "tile_size"; // (x,y) in pixels
+static const std::string TRUE_KW = "true";
-using namespace std; // tmp drb
+static const ossimTrace traceDebug("ossimWriter:debug");
ossimWriter::ossimWriter()
: ossimImageFileWriter(),
m_str(0),
- m_ownsStreamFlag(false)
+ m_ownsStreamFlag(false),
+ m_kwl(new ossimKeywordlist()),
+ m_outputTileSize(OSSIM_DEFAULT_TILE_WIDTH, OSSIM_DEFAULT_TILE_HEIGHT)
{
+ // Set default options:
+ ossim::defaultTileSize(m_outputTileSize);
+
+ m_kwl->addPair( ALIGN_TILES_KW, TRUE_KW );
+ m_kwl->addPair( BLOCK_SIZE_KW, "4096" );
+ m_kwl->addPair( FLUSH_TILES_KW, TRUE_KW );
+ m_kwl->addPair( INCLUDE_BLANK_TILES_KW, TRUE_KW );
+ m_kwl->addPair( TILE_SIZE_KW, m_outputTileSize.toString().string() );
}
ossimWriter::~ossimWriter()
{
close();
+
+ // Not a leak, ref ptr.
+ m_kwl = 0;
}
void ossimWriter::close()
@@ -70,7 +92,7 @@ ossimString ossimWriter::getClassName() const
ossimString ossimWriter::getExtension() const
{
ossimString result = "";
- if ( theOutputImageType == "ttbs" ) // tiled tiff band separate
+ if ( theOutputImageType == "ossim_ttbs" ) // tiled tiff band separate
{
result = "tif";
}
@@ -146,6 +168,9 @@ bool ossimWriter::writeFile()
if ( status )
{
status = writeStream();
+
+ // Flush and close the stream.
+ close();
}
}
@@ -167,6 +192,14 @@ bool ossimWriter::writeStream()
{
if ( theOutputImageType == "ossim_ttbs" )
{
+ if ( (theInputConnection->getTileWidth() !=
+ static_cast<ossim_uint32>(m_outputTileSize.x)) ||
+ (theInputConnection->getTileHeight() !=
+ static_cast<ossim_uint32>(m_outputTileSize.y)) )
+ {
+ theInputConnection->setTileSize(m_outputTileSize);
+ }
+
status = writeStreamTtbs();
}
}
@@ -232,10 +265,7 @@ bool ossimWriter::writeTiffHdr()
us16 = 0;
m_str->write( (const char*)&us16, 2 );
- //---
- // Offset to first IFD(image file directory).
- // This will be updated by writeTiffTags method.
- //---
+ // Offset to the IFD(image file directory).
ossim_uint64 ul64 = 16;
m_str->write( (const char*)&ul64, 8 );
@@ -257,24 +287,19 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
mapProj = dynamic_cast<ossimMapProjection*>( proj.get() );
}
- // Seek back and set the image file dectory offset(ifd).
- std::streamoff currentPos = m_str->tellp();
-
- m_str->seekp( 8, std::ios_base::beg );
+ // Seek to the IFD.
+ m_str->seekp( 16, std::ios_base::beg );
- ossim_uint64 ifdOffset = (ossim_uint64)currentPos;
- m_str->write( (const char*)&ifdOffset, 8 );
+ // tag count, this will be rewritten at the end:
+ ossim_uint64 tagCount = 0;
+ m_str->write( (const char*)&tagCount, 8 );
- // Seek back to ifd:
- m_str->seekp( currentPos, std::ios_base::beg );
-
- // tag count:
- ossim_uint64 ul64 = mapProj.valid() ? 18 : 14; // tmp drb
- m_str->write( (const char*)&ul64, 8 );
-
- // Set the sart position for array writing.
- std::streamoff arrayWritePos = m_str->tellp();
- arrayWritePos += 24 * 20; // tmp drb
+ //---
+ // This is where the tile offsets, tile byte counts and arrays bytes are
+ // written. Starting at byte position 512 which gives from
+ // 16 -> 512(496 bytes) to write tags.
+ //---
+ std::streamoff arrayWritePos = 512;
// Used throughout:
ossim_uint16 tag;
@@ -298,6 +323,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
value_ui32 = theAreaOfInterest.width();
writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
}
+ ++tagCount;
// image length tag 257:
tag = ossim::OTIFFTAG_IMAGELENGTH;
@@ -311,9 +337,10 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
else
{
type = ossim::OTIFF_LONG;
- value_ui32 = theAreaOfInterest.width();
+ value_ui32 = theAreaOfInterest.height();
writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
- }
+ }
+ ++tagCount;
// bits per sample tag 258:
tag = ossim::OTIFFTAG_BITSPERSAMPLE;
@@ -329,6 +356,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
std::vector<ossim_uint16> v(count, value_ui16);
writeTiffTag<ossim_uint16>( tag, type, count, &v.front(), arrayWritePos );
}
+ ++tagCount;
// compression tag 259:
tag = ossim::OTIFFTAG_COMPRESSION;
@@ -336,6 +364,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
count = 1;
value_ui16 = ossim::COMPRESSION_NONE; // tmp only uncompressed supported.
writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
+ ++tagCount;
// photo interpretation tag 262:
tag = ossim::OTIFFTAG_PHOTOMETRIC;
@@ -349,8 +378,8 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
{
value_ui16 = ossim::OPHOTO_MINISBLACK;
}
-
writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
+ ++tagCount;
// samples per pixel tag 277:
tag = ossim::OTIFFTAG_SAMPLESPERPIXEL;
@@ -358,47 +387,57 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
count = 1;
value_ui16 = theInputConnection->getNumberOfOutputBands();
writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
+ ++tagCount;
// Writes two tags 280 and 281:
- writeMinMaxTiffTags( minBands, maxBands, arrayWritePos );
-
+ if ( writeMinMaxTiffTags( arrayWritePos ) == true )
+ {
+ tagCount += 2;
+ }
+
// planar conf tag 284:
tag = ossim::OTIFFTAG_PLANARCONFIG;
type = ossim::OTIFF_SHORT;
count = 1;
value_ui16 = ossim::OTIFFTAG_PLANARCONFIG_SEPARATE;
writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
-
- // tile width tag 322:
- tag = ossim::OTIFFTAG_TILEWIDTH;
- count = 1;
- if ( theInputConnection->getTileWidth() <= OSSIM_DEFAULT_MAX_PIX_UINT16 )
- {
- type = ossim::OTIFF_SHORT;
- value_ui16 = (ossim_uint16)theInputConnection->getTileWidth();
- writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
- }
- else
- {
- type = ossim::OTIFF_LONG;
- value_ui32 = theAreaOfInterest.width();
- writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
- }
+ ++tagCount;
- // tile length tag 323:
- tag = ossim::OTIFFTAG_TILELENGTH;
- count = 1;
- if ( theInputConnection->getTileHeight() <= OSSIM_DEFAULT_MAX_PIX_UINT16 )
+ if ( isTiled() )
{
- type = ossim::OTIFF_SHORT;
- value_ui16 = (ossim_uint16)theInputConnection->getTileWidth();
- writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
- }
- else
- {
- type = ossim::OTIFF_LONG;
- value_ui32 = theAreaOfInterest.width();
- writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
+ // tile width tag 322:
+ tag = ossim::OTIFFTAG_TILEWIDTH;
+ count = 1;
+ if ( m_outputTileSize.x <= OSSIM_DEFAULT_MAX_PIX_UINT16 )
+ {
+ type = ossim::OTIFF_SHORT;
+ value_ui16 = (ossim_uint16)m_outputTileSize.x;
+ writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
+ }
+ else
+ {
+ type = ossim::OTIFF_LONG;
+ value_ui32 = (ossim_uint32)m_outputTileSize.x;
+ writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
+ }
+ ++tagCount;
+
+ // tile length tag 323:
+ tag = ossim::OTIFFTAG_TILELENGTH;
+ count = 1;
+ if ( m_outputTileSize.y <= OSSIM_DEFAULT_MAX_PIX_UINT16 )
+ {
+ type = ossim::OTIFF_SHORT;
+ value_ui16 = (ossim_uint16)m_outputTileSize.y;
+ writeTiffTag<ossim_uint16>( tag, type, count, &value_ui16, arrayWritePos );
+ }
+ else
+ {
+ type = ossim::OTIFF_LONG;
+ value_ui32 = (ossim_uint32)m_outputTileSize.y;
+ writeTiffTag<ossim_uint32>( tag, type, count, &value_ui32, arrayWritePos );
+ }
+ ++tagCount;
}
// tile offsets tag 324:
@@ -406,12 +445,14 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
count = tile_offsets.size();
type = ossim::OTIFF_LONG8;
writeTiffTag<ossim_uint64>( tag, type, count, &tile_offsets.front(), arrayWritePos );
+ ++tagCount;
// tile byte counts tag 325:
tag = ossim::OTIFFTAG_TILEBYTECOUNTS;
count = tile_byte_counts.size();
type = ossim::OTIFF_LONG8;
writeTiffTag<ossim_uint64>( tag, type, count, &tile_byte_counts.front(), arrayWritePos );
+ ++tagCount;
// sample format tag 339:
tag = ossim::OTIFFTAG_SAMPLEFORMAT;
@@ -427,9 +468,13 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
std::vector<ossim_uint16> v(count, value_ui16);
writeTiffTag<ossim_uint16>( tag, type, count, &v.front(), arrayWritePos );
}
+ ++tagCount;
// Writes two tags 340 and 341 (conditional on scalar type):
- writeSMinSMaxTiffTags( minBands, maxBands, arrayWritePos );
+ if ( writeSMinSMaxTiffTags( minBands, maxBands, arrayWritePos ) == true )
+ {
+ tagCount += 2;
+ }
// Write geo keys if valid map projection:
if ( mapProj.valid() )
@@ -461,6 +506,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
vf[1] = scale.y;
vf[2] = 0.0;
writeTiffTag<ossim_float64>( tag, type, count, &vf.front(), arrayWritePos );
+ ++tagCount;
// model tie point tag 33992:
tag = ossim::OMODEL_TIE_POINT_TAG;
@@ -474,6 +520,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
vf[4] = tie.y; // latitude of northing
vf[5] = 0.0;
writeTiffTag<ossim_float64>( tag, type, count, &vf.front(), arrayWritePos );
+ ++tagCount;
// geo key directory tag 34735:
tag = ossim::OGEO_KEY_DIRECTORY_TAG;
@@ -556,6 +603,7 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
count = vs.size();
vs[3] = (count / 4) - 1;
writeTiffTag<ossim_uint16>( tag, type, count, &vs.front(), arrayWritePos );
+ ++tagCount;
// geo double params tag 33550:
tag = ossim::OGEO_DOUBLE_PARAMS_TAG;
@@ -565,110 +613,80 @@ bool ossimWriter::writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
vf[0] = mapProj->getDatum()->ellipsoid()->a();
vf[1] = mapProj->getDatum()->ellipsoid()->b();
writeTiffTag<ossim_float64>( tag, type, count, &vf.front(), arrayWritePos );
+ ++tagCount;
}
- // Last write is zero indicading no more ifds.
+ // Write trailing zero indicading no more IFDs.
ossim_uint64 offsetToNextIfd = 0;
m_str->write( (const char*)&offsetToNextIfd, 8 );
+ // Seek back and re-write the tag count.
+ m_str->seekp( 16, std::ios_base::beg );
+ m_str->write( (const char*)&tagCount, 8 );
+
status = m_str->good();
return status;
}
-bool ossimWriter::writeMinMaxTiffTags( const vector<ossim_float64>& minBands,
- const vector<ossim_float64>& maxBands,
- std::streamoff& arrayWritePos )
+bool ossimWriter::writeMinMaxTiffTags( std::streamoff& arrayWritePos )
{
bool status = true;
-
- if(minBands.size() && maxBands.size())
- {
- ossim_float64 minValue = *std::min_element(minBands.begin(), minBands.end());
- ossim_float64 maxValue = *std::max_element(maxBands.begin(), maxBands.end());
- switch( theInputConnection->getOutputScalarType() )
+ // DEFAULT for OSSIM_UINT32.
+ ossim_uint16 minValue = 1;
+ ossim_uint16 maxValue = 255;
+
+ switch( theInputConnection->getOutputScalarType() )
+ {
+ case OSSIM_UINT8:
{
- case OSSIM_USHORT11:
- {
- ossim_uint16 v = 0;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = 2047;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- case OSSIM_USHORT12:
- {
- ossim_uint16 v = 0;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = 4095;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- case OSSIM_USHORT13:
- {
- ossim_uint16 v = 0;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = 8191;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- case OSSIM_USHORT14:
- {
- ossim_uint16 v = 0;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = 16383;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- case OSSIM_USHORT15:
- {
- ossim_uint16 v = 0;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = 32767;
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- case OSSIM_UINT8:
- case OSSIM_UINT16:
- {
- ossim_uint16 v = static_cast<ossim_uint16>(minValue);
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- v = static_cast<ossim_uint16>(maxValue);
- writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
- ossim::OTIFF_SHORT,
- 1, &v, arrayWritePos );
- break;
- }
- default:
- {
- status = false;
- break;
- }
+ break; // defaulted above
}
+ case OSSIM_USHORT11:
+ {
+ maxValue = 2047;
+ break;
+ }
+ case OSSIM_USHORT12:
+ {
+ maxValue = 4095;
+ break;
+ }
+ case OSSIM_USHORT13:
+ {
+ maxValue = 8191;
+ break;
+ }
+ case OSSIM_USHORT14:
+ {
+ maxValue = 16383;
+ break;
+ }
+ case OSSIM_USHORT15:
+ {
+ maxValue = 32767;
+ break;
+ }
+ case OSSIM_UINT16:
+ {
+ maxValue = 65535;
+ break;
+ }
+ default:
+ status = false;
+ }
+
+ if ( status )
+ {
+ writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MINSAMPLEVALUE,
+ ossim::OTIFF_SHORT,
+ 1, &minValue, arrayWritePos );
+ writeTiffTag<ossim_uint16>( ossim::OTIFFTAG_MAXSAMPLEVALUE,
+ ossim::OTIFF_SHORT,
+ 1, &maxValue, arrayWritePos );
}
+
return status;
}
@@ -676,7 +694,7 @@ bool ossimWriter::writeSMinSMaxTiffTags( const vector<ossim_float64>& minBands,
const vector<ossim_float64>& maxBands,
std::streamoff& arrayWritePos )
{
- bool status = true;
+ bool status = false;
if(minBands.size() && maxBands.size())
{
@@ -700,11 +718,11 @@ bool ossimWriter::writeSMinSMaxTiffTags( const vector<ossim_float64>& minBands,
writeTiffTag<ossim_float32>( ossim::OTIFFTAG_SMAXSAMPLEVALUE,
ossim::OTIFF_FLOAT,
1, &v, arrayWritePos );
+ status = true;
break;
}
default:
{
- status = false;
break;
}
}
@@ -712,8 +730,6 @@ bool ossimWriter::writeSMinSMaxTiffTags( const vector<ossim_float64>& minBands,
return status;
}
-
-
template <class T>
void ossimWriter::writeTiffTag(
ossim_uint16 tag, ossim_uint16 type, ossim_uint64 count,
@@ -762,25 +778,58 @@ bool ossimWriter::writeTiffTilesBandSeparate( std::vector<ossim_uint64>& tile_of
std::vector<ossim_float64>& minBands,
std::vector<ossim_float64>& maxBands )
{
- static const char* const MODULE = "ossimTiffWriter::writeToTilesBandSeparate";
- if (traceDebug()) CLOG << " Entered." << std::endl;
+ static const char* const MODULE = "ossimWriter::writeToTilesBandSeparate";
+ if ( traceDebug() ) CLOG << " Entered...\n";
// Start the sequence at the first tile.
theInputConnection->setToStartOfSequence();
+ // Control flags:
+ bool alignTiles = getAlignTilesFlag();
+ bool flushTiles = getFlushTilesFlag();
+ bool writeBlanks = getWriteBlanksFlag();
+ bool computeMinMax = needsMinMax();
+
+ // Block size for write:
+ const std::streamsize BLOCK_SIZE = getBlockSize();
+
const ossim_int32 BANDS = (ossim_int32)theInputConnection->getNumberOfOutputBands();
const ossim_int32 TILES_WIDE = (ossim_int32)theInputConnection->getNumberOfTilesHorizontal();
const ossim_int32 TILES_TOTAL = (ossim_int32)theInputConnection->getNumberOfTiles();
+ if (traceDebug())
+ {
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << "align tiles flag: " << alignTiles
+ << "\nflush tiles flag: " << flushTiles
+ << "\nwrite blanks flag: " << writeBlanks
+ << "\ncompute min max flag: " << computeMinMax
+ << "\nwrite block size: " << BLOCK_SIZE
+ << "\nBANDS: " << BANDS
+ << "\nTILES_WIDE: " << TILES_WIDE
+ << "\nTILES_TOTAL: " << TILES_TOTAL << "\n";
+ }
+
tile_offsets.resize( TILES_TOTAL*BANDS );
tile_byte_counts.resize( TILES_TOTAL*BANDS );
+ ossimDataObjectStatus tileStatus = OSSIM_STATUS_UNKNOWN;
ossim_int64 ossimTileIndex = 0;
ossim_int64 tiffTileIndex = 0;
ossim_int64 tileSizeInBytes = 0;
ossim_int64 bandOffsetInBytes = 0;
- std::streamoff startPos = m_str->tellp();
+ //---
+ // Adjust the starting file position to make room for IFD tags, tile offset
+ // and tile byte counts and arrays.
+ //
+ // Assuming:
+ // IFD start = 16, end 512, gives 496 bytes for tags.
+ // Array section start = 512, end is start + (16 * tile_count * bands) + 256 bytes
+ // for geotiff array bytes.
+ //---
+ std::streamsize startPos = 512 + 16 * TILES_TOTAL * BANDS + 256;
+
while ( ossimTileIndex < TILES_TOTAL )
{
ossimRefPtr<ossimImageData> id = theInputConnection->getNextTile();
@@ -793,6 +842,8 @@ bool ossimWriter::writeTiffTilesBandSeparate( std::vector<ossim_uint64>& tile_of
<< std::endl;
return false;
}
+
+ tileStatus = id->getDataObjectStatus();
if ( ossimTileIndex == 0 )
{
@@ -800,61 +851,101 @@ bool ossimWriter::writeTiffTilesBandSeparate( std::vector<ossim_uint64>& tile_of
bandOffsetInBytes = tileSizeInBytes * TILES_TOTAL;
}
- // Compute running min, max.
- id->computeMinMaxPix(minBands, maxBands);
+ if ( computeMinMax )
+ {
+ if ( (tileStatus == OSSIM_FULL) || (tileStatus == OSSIM_PARTIAL) )
+ {
+ // Compute running min, max.
+ id->computeMinMaxPix(minBands, maxBands);
+ }
+ }
// Band loop.
for (ossim_int32 band=0; band < BANDS; ++band)
{
- // Grab a pointer to the tile for the band.
- const char* data = (const char*)id->getBuf(band);
+ tiffTileIndex = ossimTileIndex + band * TILES_TOTAL;
- // Compress data here(future maybe, i.e. jpeg, j2k...
-
- //---
- // Write the tile.
- // Note: tiles laid out, all the red tiles, all the green tiles all the
- // blue tiles.
- //---
- if(data)
+ if ( (writeBlanks == true) || (tileStatus == OSSIM_FULL) || (tileStatus == OSSIM_PARTIAL) )
{
- // Compute the stream position:
- std::streamoff pos = startPos + ossimTileIndex * tileSizeInBytes +
- band * bandOffsetInBytes;
- m_str->seekp( pos );
-
- if ( m_str->good() )
+ // Grab a pointer to the tile for the band.
+ const char* data = (const char*)id->getBuf(band);
+
+ // Compress data here(future maybe, i.e. jpeg, j2k...
+
+ //---
+ // Write the tile.
+ // Note: tiles laid out, all the red tiles, all the green tiles all the
+ // blue tiles.
+ //---
+ if(data)
{
- tiffTileIndex = ossimTileIndex + band * TILES_TOTAL;
- tile_offsets[ tiffTileIndex ] = (ossim_uint64)pos;
- tile_byte_counts[ tiffTileIndex ] = (ossim_uint64)tileSizeInBytes;
+ // Compute the stream position:
+ std::streampos pos = startPos + ossimTileIndex * tileSizeInBytes +
+ band * bandOffsetInBytes;
+
+ if ( alignTiles )
+ {
+ // Snap to block boundary:
+ std::streampos overflow = pos % BLOCK_SIZE;
+ if ( overflow > 0 )
+ {
+ pos += BLOCK_SIZE - overflow;
+ }
+ }
- // Write the tile to stream:
- m_str->write( data, (std::streamsize)tileSizeInBytes);
+ m_str->seekp( pos );
- // Check stream:
- if ( m_str->fail() == true )
+ if ( m_str->good() )
+ {
+ tile_offsets[ tiffTileIndex ] = (ossim_uint64)pos;
+ tile_byte_counts[ tiffTileIndex ] = (ossim_uint64)tileSizeInBytes;
+
+ // Write the tile to stream:
+ m_str->write( data, (std::streamsize)tileSizeInBytes);
+
+ if ( flushTiles )
+ {
+ m_str->flush();
+ }
+
+ // Check stream:
+ if ( m_str->fail() == true )
+ {
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << MODULE << " ERROR:\nWrite error on tiff tile: " << ossimTileIndex
+ << std::endl;
+ return false;
+ }
+ }
+ else
{
ossimNotify(ossimNotifyLevel_DEBUG)
- << MODULE << " ERROR:\nWrite error on tiff tile: " << ossimTileIndex
- << std::endl;
+ << MODULE << " ERROR:\nStream has gone bad!" << std::endl;
return false;
}
+
}
else
{
- ossimNotify(ossimNotifyLevel_DEBUG)
- << MODULE << " ERROR:\nStream has gone bad!" << std::endl;
+ ossimNotify(ossimNotifyLevel_WARN)
+ << MODULE << " ERROR:\nNull input tile: " << ossimTileIndex
+ << std::endl;
return false;
}
-
}
else
{
- ossimNotify(ossimNotifyLevel_WARN)
- << MODULE << " ERROR:\nNull input tile: " << ossimTileIndex
- << std::endl;
- return false;
+ //---
+ // Writing sparse tiff.
+ // Set the offset and byte count to 0 to indicate blank tile.
+ //---
+ if (traceDebug())
+ {
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << "sparse blank tile[" << tiffTileIndex << "]: " << tiffTileIndex << "\n";
+ }
+ tile_offsets[ tiffTileIndex ] = 0;
+ tile_byte_counts[ tiffTileIndex ] = 0;
}
} // End of band loop.
@@ -876,7 +967,7 @@ bool ossimWriter::writeTiffTilesBandSeparate( std::vector<ossim_uint64>& tile_of
} // End: while ( ossimTileIndex < TILES_TOTAL )
- if (traceDebug()) CLOG << " Exited." << std::endl;
+ if ( traceDebug() ) CLOG << " Exited...\n";
return m_str->good();
}
@@ -892,6 +983,200 @@ bool ossimWriter::setOutputStream(std::ostream& stream)
return true;
}
+void ossimWriter::setTileSize(const ossimIpt& tileSize)
+{
+ if ( (tileSize.x % 16) || (tileSize.y % 16) )
+ {
+ if(traceDebug())
+ {
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << "ossimWriter::setTileSize ERROR:"
+ << "\nTile size must be a multiple of 16!"
+ << "\nSize remains: " << m_outputTileSize
+ << std::endl;
+ }
+ }
+ else
+ {
+ m_outputTileSize = tileSize;
+
+ // For save state:
+ m_kwl->addPair( TILE_SIZE_KW, m_outputTileSize.toString().string() );
+ }
+}
+
+const ossimIpt& ossimWriter::getOutputTileSize() const
+{
+ return m_outputTileSize;
+}
+
+bool ossimWriter::saveState( ossimKeywordlist& kwl, const char* prefix) const
+{
+ // Lazy man save state...
+ kwl.add( prefix, *(m_kwl.get()), true );
+ return ossimImageFileWriter::saveState(kwl, prefix);
+}
+
+bool ossimWriter::loadState(const ossimKeywordlist& kwl, const char* prefix)
+{
+ bool result = false;
+ if ( ossimImageFileWriter::loadState(kwl, prefix) )
+ {
+ if ( theOutputImageType!="ossim_ttbs")
+ {
+ result = true;
+
+ std::string pfx = prefix?prefix:"";
+ std::string value;
+
+ value = kwl.findKey( pfx, ALIGN_TILES_KW );
+ if ( value.size() )
+ {
+ m_kwl->addPair( ALIGN_TILES_KW, value, true );
+ }
+
+ value = kwl.findKey( pfx, BLOCK_SIZE_KW );
+ if ( value.size() )
+ {
+ m_kwl->addPair( BLOCK_SIZE_KW, value, true );
+ }
+
+ value = kwl.findKey( pfx, FLUSH_TILES_KW );
+ if ( value.size() )
+ {
+ m_kwl->addPair( FLUSH_TILES_KW, value, true );
+ }
+
+ value = kwl.findKey( pfx, INCLUDE_BLANK_TILES_KW );
+ if ( value.size() )
+ {
+ m_kwl->addPair( INCLUDE_BLANK_TILES_KW, value, true );
+ }
+
+ value = kwl.findKey( pfx, TILE_SIZE_KW );
+ if ( value.size() )
+ {
+ m_outputTileSize.toPoint(value);
+ m_kwl->addPair( TILE_SIZE_KW, m_outputTileSize.toString().string(), true );
+ }
+ }
+ }
+
+ return result;
+}
+
+void ossimWriter::setProperty(ossimRefPtr<ossimProperty> property)
+{
+ if( property.valid() )
+ {
+ // See if it's one of our properties:
+ std::string key = property->getName().string();
+
+ if ( traceDebug() )
+ {
+ ossimString value;
+ property->valueToString(value);
+
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << "ossimWriter::setProperty DEBUG:"
+ << "\nkey: " << key
+ << "\nvalue: " << value << "\n";
+ }
+
+ if ( ( key == ALIGN_TILES_KW ) ||
+ ( key == BLOCK_SIZE_KW ) ||
+ ( key == FLUSH_TILES_KW ) ||
+ ( key == INCLUDE_BLANK_TILES_KW ) )
+ {
+ ossimString value;
+ property->valueToString(value);
+ m_kwl->addPair( key, value.string(), true );
+ }
+ else if ( key == TILE_SIZE_KW )
+ {
+ // Comes in as a single int, e.g.: 256
+ ossimString value;
+ property->valueToString(value);
+ m_outputTileSize.x = value.toInt32();
+ m_outputTileSize.y = m_outputTileSize.x;
+
+ // Store in keywordlist / save state as a point, e.g.: ( 256, 256 )
+ m_kwl->addPair( key, m_outputTileSize.toString().string(), true );
+ }
+ else
+ {
+ ossimImageFileWriter::setProperty(property);
+ }
+ }
+}
+
+ossimRefPtr<ossimProperty> ossimWriter::getProperty(const ossimString& name)const
+{
+ ossimRefPtr<ossimProperty> prop = 0;
+
+ if ( name.string() == ALIGN_TILES_KW )
+ {
+ std::string value = m_kwl->findKey( ALIGN_TILES_KW );
+ ossimRefPtr<ossimBooleanProperty> boolProp =
+ new ossimBooleanProperty(name, ossimString(value).toBool());
+ prop = boolProp.get();
+ }
+ else if( name == BLOCK_SIZE_KW )
+ {
+ // Property a single int, e.g.: 4096
+ ossim_int64 blockSize = getBlockSize();
+ ossimRefPtr<ossimStringProperty> stringProp =
+ new ossimStringProperty(name, ossimString::toString(blockSize), false); // editable flag
+ prop = stringProp.get();
+ }
+ else if ( name.string() == FLUSH_TILES_KW )
+ {
+ std::string value = m_kwl->findKey( FLUSH_TILES_KW );
+ ossimRefPtr<ossimBooleanProperty> boolProp =
+ new ossimBooleanProperty(name, ossimString(value).toBool());
+ prop = boolProp.get();
+ }
+ else if ( name.string() == INCLUDE_BLANK_TILES_KW )
+ {
+ std::string value = m_kwl->findKey( INCLUDE_BLANK_TILES_KW );
+ ossimRefPtr<ossimBooleanProperty> boolProp =
+ new ossimBooleanProperty(name, ossimString(value).toBool());
+ prop = boolProp.get();
+ }
+ else if( name == TILE_SIZE_KW )
+ {
+ // Property a single int, e.g.: 256
+ ossimRefPtr<ossimStringProperty> stringProp =
+ new ossimStringProperty(name, ossimString::toString(m_outputTileSize.x), false); // editable flag
+ stringProp->setReadOnlyFlag(false);
+ stringProp->setChangeType(ossimProperty::ossimPropertyChangeType_AFFECTS_OTHERS);
+ stringProp->addConstraint(ossimString("16"));
+ stringProp->addConstraint(ossimString("32"));
+ stringProp->addConstraint(ossimString("64"));
+ stringProp->addConstraint(ossimString("128"));
+ stringProp->addConstraint(ossimString("256"));
+ stringProp->addConstraint(ossimString("512"));
+ stringProp->addConstraint(ossimString("1024"));
+ stringProp->addConstraint(ossimString("2048"));
+ prop = stringProp.get();
+ }
+ else
+ {
+ prop = ossimImageFileWriter::getProperty(name);
+ }
+ return prop;
+}
+
+void ossimWriter::getPropertyNames(std::vector<ossimString>& propertyNames) const
+{
+ propertyNames.push_back(ossimString(ALIGN_TILES_KW));
+ propertyNames.push_back(ossimString(BLOCK_SIZE_KW));
+ propertyNames.push_back(ossimString(FLUSH_TILES_KW));
+ propertyNames.push_back(ossimString(INCLUDE_BLANK_TILES_KW));
+ propertyNames.push_back(ossimString(TILE_SIZE_KW));
+ ossimImageFileWriter::getPropertyNames(propertyNames);
+}
+
ossim_uint16 ossimWriter::getTiffSampleFormat() const
{
ossim_uint16 result = 0;
@@ -925,3 +1210,86 @@ ossim_uint16 ossimWriter::getTiffSampleFormat() const
return result;
}
+
+bool ossimWriter::isTiled() const
+{
+ return ( theOutputImageType == "ossim_ttbs" );
+}
+
+bool ossimWriter::getAlignTilesFlag() const
+{
+ bool result = true; // default
+ std::string value = m_kwl->findKey( ALIGN_TILES_KW );
+ if ( value.size() )
+ {
+ result = ossimString(value).toBool();
+ }
+ return result;
+}
+
+ossim_int64 ossimWriter::getBlockSize() const
+{
+ ossim_int64 result = 4096; // default
+ std::string value = m_kwl->findKey( BLOCK_SIZE_KW );
+ if ( value.size() )
+ {
+ result = ossimString(value).toInt64();
+
+ // Disallow anything not on 1024 boundary.
+ if ( result % 1024 )
+ {
+ result = 4096;
+ ossimNotify(ossimNotifyLevel_DEBUG)
+ << "ossimWriter::getBlockSize ERROR:"
+ << "\nBlock size MUST be a multiple of 1024!"
+ << "\nBlock size remains: " << result
+ << std::endl;
+ }
+ }
+ return result;
+}
+
+bool ossimWriter::getFlushTilesFlag() const
+{
+ bool result = true; // default
+ std::string value = m_kwl->findKey( FLUSH_TILES_KW );
+ if ( value.size() )
+ {
+ result = ossimString(value).toBool();
+ }
+ return result;
+}
+
+bool ossimWriter::getWriteBlanksFlag() const
+{
+ bool result = true; // default
+ std::string value = m_kwl->findKey( INCLUDE_BLANK_TILES_KW );
+ if ( value.size() )
+ {
+ result = ossimString(value).toBool();
+ }
+ return result;
+}
+
+bool ossimWriter::needsMinMax() const
+{
+ bool result = false;
+ switch( theInputConnection->getOutputScalarType() )
+ {
+ case OSSIM_SINT16:
+ case OSSIM_UINT32:
+ case OSSIM_FLOAT32:
+ case OSSIM_FLOAT64:
+ case OSSIM_NORMALIZED_FLOAT:
+ case OSSIM_NORMALIZED_DOUBLE:
+ {
+ result = true;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return result;
+}
diff --git a/src/init/JsonConfig.cpp b/src/init/JsonConfig.cpp
new file mode 100644
index 0000000..841a465
--- /dev/null
+++ b/src/init/JsonConfig.cpp
@@ -0,0 +1,467 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#include <ossim/init/JsonConfig.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimException.h>
+#include <ossim/base/ossimPreferences.h>
+#include <ossim/base/ossimNotify.h>
+#include <ossim/base/ossimDirectory.h>
+#include <memory>
+
+using namespace std;
+
+namespace ossim
+{
+JsonParam JsonConfig::s_nullParam;
+
+JsonParam::JsonParam(const ossimString& argname,
+ const ossimString& arglabel,
+ const ossimString& argdescr,
+ ParamType argparamType,
+ void* value)
+: _name (argname),
+ _label (arglabel),
+ _descr (argdescr),
+ _type (argparamType),
+ _value(0)
+{
+ setValue(value);
+}
+
+JsonParam::JsonParam(const JsonParam& copy)
+: _label (copy._label),
+ _name (copy._name),
+ _descr (copy._descr),
+ _type (copy._type),
+ _value (0)
+{
+ setValue(copy._value);
+}
+
+void JsonParam::setValue(void* value)
+{
+ if (!value)
+ return;
+
+ switch (_type)
+ {
+ case JsonParam::BOOL:
+ _value = new bool;
+ memcpy(_value, value, sizeof(bool));
+ break;
+ case JsonParam::INT:
+ _value = new int;
+ memcpy(_value, value, sizeof(int));
+ break;
+ case JsonParam::UINT:
+ _value = new unsigned int;
+ memcpy(_value, value, sizeof(unsigned int));
+ break;
+ case JsonParam::FLOAT:
+ _value = new double;
+ memcpy(_value, value, sizeof(double));
+ break;
+ case JsonParam::STRING:
+ _value = new string(*(string*)(value));
+ break;
+ case JsonParam::VECTOR:
+ _value = new vector<double>(*(vector<double>*)(value));
+ break;
+ default:
+ _value = 0;
+ }
+}
+
+void JsonParam::resetValue()
+{
+ if (!_value)
+ return;
+
+ switch (_type)
+ {
+ case JsonParam::BOOL:
+ delete (bool*)_value;
+ break;
+ case JsonParam::INT:
+ case JsonParam::UINT:
+ delete (int*)_value;
+ break;
+ case JsonParam::FLOAT:
+ delete (double*)_value;
+ break;
+ case JsonParam::STRING:
+ delete (string*)_value;
+ break;
+ case JsonParam::VECTOR:
+ ((vector<double>*)_value)->clear();
+ delete (vector<double>*)_value;
+ break;
+ default:
+ break;
+ }
+ _value = 0;
+}
+
+bool JsonParam::loadJSON(const Json::Value& paramNode)
+{
+ try
+ {
+ _name = paramNode["name"].asString();
+ _label = paramNode["label"].asString();
+ _descr = paramNode["descr"].asString();
+ Json::Value value = paramNode["value"];
+
+ ossimString ptype = paramNode["type"].asString();
+ if (ptype.empty() || _name.empty())
+ return false;
+
+ ptype.upcase();
+
+ if (ptype == "VECTOR")
+ {
+ _type = JsonParam::VECTOR;
+ vector<double> v;
+ if (value.isArray())
+ {
+ int n = value.size();
+ for (unsigned int j=0; j<n; ++j)
+ v.push_back(value[j].asDouble());
+ }
+ setValue(&v);
+ }
+ else
+ {
+ // Screen for param value list as found in the default config JSONs. Pick the first element
+ // as the default:
+ if (value.isArray())
+ value = value[0];
+
+ if (ptype == "BOOL")
+ {
+ _type = JsonParam::BOOL;
+ bool v = value.asBool();
+ setValue(&v);
+ }
+ else if (ptype == "UINT")
+ {
+ _type = JsonParam::UINT;
+ unsigned int v = value.asUInt();
+ setValue(&v);
+ }
+ else if (ptype == "INT")
+ {
+ _type = JsonParam::INT;
+ int v = value.asInt();
+ setValue(&v);
+ }
+ else if (ptype == "FLOAT")
+ {
+ _type = JsonParam::FLOAT;
+ double v = value.asDouble();
+ setValue(&v);
+ }
+ else if (ptype == "STRING")
+ {
+ _type = JsonParam::STRING;
+ string v = value.asString();
+ setValue(&v);
+ }
+ }
+ }
+ catch (exception& e)
+ {
+ ossimNotify(ossimNotifyLevel_WARN)<<"JsonParam::loadJSON() parse error encountered. Ignoring "
+ "but should check the JsonConfig JSON for parameter <"<<_name<<">."<<endl;
+ return false;
+ }
+ return true;
+}
+
+void JsonParam::saveJSON(Json::Value& paramNode) const
+{
+ vector<double>& v = *(vector<double>*)_value; // maybe not used since maybe not valid cast
+ unsigned int n = 0;
+ int i;
+ double f;
+ string s;
+ bool b;
+
+ paramNode["name"] = _name.string();
+ paramNode["label"] = _label.string();
+ paramNode["descr"] = _descr.string();
+
+ switch (_type)
+ {
+ case JsonParam::BOOL:
+ paramNode["type"] = "bool";
+ b = *(bool*)_value;
+ paramNode["value"] = b;
+ break;
+
+ case JsonParam::INT:
+ paramNode["type"] = "int";
+ i = *(int*)_value;
+ paramNode["value"] = i;
+ break;
+
+ case JsonParam::UINT:
+ paramNode["type"] = "uint";
+ n = *(unsigned int*)_value;
+ paramNode["value"] = n;
+ break;
+
+ case JsonParam::FLOAT:
+ paramNode["type"] = "float";
+ f = *(double*)_value;
+ paramNode["value"] = f;
+ break;
+
+ case JsonParam::STRING:
+ paramNode["type"] = "string";
+ s = *(string*)_value;
+ paramNode["value"] = s;
+ break;
+
+ case JsonParam::VECTOR:
+ paramNode["type"] = "vector";
+ n = v.size();
+ for (unsigned int j=0; j<n; ++j)
+ paramNode["value"][j] = v[j];
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool JsonParam::asBool() const
+{
+ if (_type == BOOL)
+ return *(bool*)_value;
+ return false;
+}
+
+unsigned int JsonParam::asUint() const
+{
+ if (_type == UINT)
+ return *(unsigned int*)_value;
+ return 0;
+}
+
+int JsonParam::asInt() const
+{
+ if ((_type == INT) || (_type == UINT))
+ return *(int*)_value;
+ return 0;
+}
+
+double JsonParam::asFloat() const
+{
+ if (_type == FLOAT)
+ return *(double*)_value;
+ return ossim::nan();
+}
+
+std::string JsonParam::asString() const
+{
+ if (_type == STRING)
+ return *(string*)_value;
+ return "";
+}
+
+void JsonParam::asVector(std::vector<double>& v) const
+{
+ v.clear();
+ if (_type == VECTOR)
+ v = *(vector<double>*)_value;
+}
+
+ostream& operator<<(std::ostream& out, const JsonParam& obj)
+{
+ Json::Value jsonNode;
+ obj.saveJSON(jsonNode);
+ out << jsonNode << endl;
+ return out;
+}
+
+//-------------------------------------------------------------
+
+JsonConfig::JsonConfig()
+{
+ // This ctor could eventually curl a spring config server for the param JSON. For now it
+ // is reading the installed share/ossim system directory for config JSON files.
+
+ // The previous parameters list is cleared first for a fresh start:
+ m_paramsMap.clear();
+ ossimFilename configFilename;
+ try
+ {
+ // First establish the directory location of the default config files:
+ ossimFilename shareName (ossimPreferences::instance()->
+ preferencesKWL().findKey( std::string( "ossim_share_directory" )));
+ if (!shareName.isDir())
+ throw ossimException("Nonexistent share drive provided for config files.");
+
+ // Fetch all JSON files:
+ ossimDirectory shareDir;
+ if (!shareDir.open(shareName))
+ throw ossimException("Share drive provided for config files is not readable.");
+ std::vector<ossimFilename> jsonFiles;
+ shareDir.findAllFilesThatMatch(jsonFiles, ".*\\.json");
+
+ // Process those that contain the "parameters" JSON node:
+ for (unsigned int i=0; i<jsonFiles.size(); i++)
+ {
+ configFilename = jsonFiles[i];
+ if (!open(configFilename))
+ throw ossimException("Bad file open or parse.");
+ }
+
+ }
+ catch (ossimException& e)
+ {
+ ossimNotify(ossimNotifyLevel_WARN)<<"JsonConfig::readConfig(): Could not open/parse "
+ "config file at <"<< configFilename << ">. Error: "<<e.what()<<endl;
+ }
+}
+
+JsonConfig::JsonConfig(const ossimFilename& configFile)
+{
+ if (!open(configFile))
+ throw ossimException("Bad file open or parse.");
+}
+
+JsonConfig::~JsonConfig()
+{
+ m_paramsMap.clear();
+}
+
+bool JsonConfig::open(const ossimFilename& configFileName)
+{
+ ifstream configFile (configFileName.string());
+ if (configFile.fail())
+ return false;
+ Json::Value jsonRoot;
+ configFile >> jsonRoot;
+ if (jsonRoot.empty())
+ return false;
+ if (jsonRoot.isMember("parameters"))
+ {
+ Json::Value& paramsNode = jsonRoot["parameters"];
+ loadJSON(paramsNode);
+ }
+ configFile.close();
+ return true;
+}
+
+JsonParam& JsonConfig::getParameter(const char* paramName)
+{
+ map<string, JsonParam>::iterator i = m_paramsMap.find(string(paramName));
+ if (i != m_paramsMap.end())
+ return i->second;
+ return s_nullParam;
+}
+
+void JsonConfig::setParameter(const JsonParam& p)
+{
+ // Tricky stuff to make sure it is a deep copy of the parameter:
+ string key = p.name().string();
+ std::map<std::string, JsonParam>::iterator iter = m_paramsMap.find(key);
+ if (iter != m_paramsMap.end())
+ m_paramsMap.erase(key);
+ m_paramsMap.emplace(key, p);
+}
+
+bool JsonConfig::paramExists(const char* paramName) const
+{
+ map<string, JsonParam>::const_iterator i = m_paramsMap.find(string(paramName));
+ if (i != m_paramsMap.end())
+ return true;
+ return false;
+}
+
+void JsonConfig::loadJSON(const Json::Value& json_node)
+{
+ Json::Value paramNode;
+
+ // Support two forms: long (with full param descriptions and types), or short (just name: value)
+ if (json_node.isArray())
+ {
+ // Long form:
+ for (unsigned int i=0; i<json_node.size(); ++i)
+ {
+ paramNode = json_node[i];
+ JsonParam p;
+ if (p.loadJSON(paramNode))
+ setParameter(p);
+ }
+ }
+ else
+ {
+ // Short form expects a prior entry in the params map whose value will be overriden here:
+ Json::Value::Members members = json_node.getMemberNames();
+ for (size_t i=0; i<members.size(); ++i)
+ {
+ JsonParam& p = getParameter(members[i].c_str());
+ if (p.name().empty())
+ {
+ ossimNotify(ossimNotifyLevel_WARN)<<"JsonConfig::loadJSON(): Attempted to override "
+ "nonexistent parameter <"<< members[i] << ">. Ignoring request."<<endl;
+ continue;
+ }
+ if (p.descr().contains("DEPRECATED"))
+ {
+ ossimNotify(ossimNotifyLevel_WARN)<<"JsonConfig::loadJSON() Parameter "<<p.name()
+ <<" "<<p.descr()<<endl;
+ continue;
+ }
+
+ // Create a full JSON representation of the named parameter from the default list, replace
+ // its value, and recreate the parameter from the updated full JSON:
+ p.saveJSON(paramNode);
+ paramNode["value"] = json_node[p.name().string()];
+ p.loadJSON(paramNode);
+ }
+ }
+}
+
+
+void JsonConfig::saveJSON(Json::Value& json_node) const
+{
+ Json::Value paramNode;
+
+ map<string, JsonParam>::const_iterator param = m_paramsMap.begin();
+ int entry = 0;
+ while (param != m_paramsMap.end())
+ {
+ param->second.saveJSON(paramNode);
+ json_node[entry++] = paramNode;
+ ++param;
+ }
+}
+
+bool JsonConfig::diagnosticLevel(unsigned int level) const
+{
+ map<string, JsonParam>::const_iterator i = m_paramsMap.find(string("diagnosticLevel"));
+ if (i != m_paramsMap.end())
+ {
+ unsigned int levelSetting = i->second.asUint();
+ return (level <= levelSetting);
+ }
+ return false;
+}
+
+std::ostream& operator<<(std::ostream& out, const JsonConfig& obj)
+{
+ Json::Value configJsonNode;
+ obj.saveJSON(configJsonNode);
+ out<<configJsonNode<<endl;
+ return out;
+}
+
+}
diff --git a/src/projection/ossimImageViewTransform.cpp b/src/projection/ossimImageViewTransform.cpp
index b8ea0f7..15e6226 100644
--- a/src/projection/ossimImageViewTransform.cpp
+++ b/src/projection/ossimImageViewTransform.cpp
@@ -306,6 +306,21 @@ ossimDrect ossimImageViewTransform::getImageToViewBounds(const ossimDrect& image
return ossimDrect(p1, p2, p3, p4);
}
+ossimDrect ossimImageViewTransform::getViewToImageBounds(const ossimDrect& viewRect)const
+{
+ ossimDpt p1;
+ ossimDpt p2;
+ ossimDpt p3;
+ ossimDpt p4;
+
+ viewToImage(viewRect.ul(), p1);
+ viewToImage(viewRect.ur(), p2);
+ viewToImage(viewRect.lr(), p3);
+ viewToImage(viewRect.ll(), p4);
+
+ return ossimDrect(p1, p2, p3, p4);
+}
+
std::ostream& ossimImageViewTransform::print(std::ostream& out) const
{
return out;
diff --git a/src/projection/ossimRpcModel.cpp b/src/projection/ossimRpcModel.cpp
index 48f20f7..96ca04d 100644
--- a/src/projection/ossimRpcModel.cpp
+++ b/src/projection/ossimRpcModel.cpp
@@ -1485,8 +1485,7 @@ bool ossimRpcModel::toJSON(std::ostream& jsonStream) const
Json::Value root;
root["isd"] = ISD;
- Json::StyledWriter writer;
- jsonStream << writer.write(root);
+ jsonStream << root;
return true;
#else
jsonStream<<"Error: JSON format not supported."<<endl;
diff --git a/src/projection/ossimSensorModel.cpp b/src/projection/ossimSensorModel.cpp
index fc131e4..2b5f772 100644
--- a/src/projection/ossimSensorModel.cpp
+++ b/src/projection/ossimSensorModel.cpp
@@ -1160,7 +1160,9 @@ void ossimSensorModel::imagingRay(const ossimDpt& image_point,
//
//*****************************************************************************
ossimSensorModel::CovMatStatus ossimSensorModel::getObsCovMat(
- const ossimDpt& /* ipos */ , NEWMAT::SymmetricMatrix& Cov, const ossim_float64 defPointingSigma)
+ const ossimDpt& /* ipos */ ,
+ NEWMAT::SymmetricMatrix& Cov,
+ const ossim_float64 defPointingSigma) const
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Mensuration error contribution
diff --git a/src/projection/ossimSensorModelTuple.cpp b/src/projection/ossimSensorModelTuple.cpp
index 0f9eaac..e2118d2 100644
--- a/src/projection/ossimSensorModelTuple.cpp
+++ b/src/projection/ossimSensorModelTuple.cpp
@@ -30,12 +30,12 @@ static const char OSSIM_ID[] = "$Id: ossimSensorModelTuple.cpp 22045 2012-12-28
#endif
ossimRpcPqeInputs::ossimRpcPqeInputs()
- : theRpcElevationAngle(ossim::nan()),
- theRpcAzimuthAngle(ossim::nan()),
- theRpcBiasError(ossim::nan()),
- theRpcRandError(ossim::nan()),
- theSurfaceNormalVector(),
- theSurfaceCovMatrix(3,3)
+: theRpcElevationAngle(ossim::nan()),
+ theRpcAzimuthAngle(ossim::nan()),
+ theRpcBiasError(ossim::nan()),
+ theRpcRandError(ossim::nan()),
+ theSurfaceNormalVector(),
+ theSurfaceCovMatrix(3,3)
{
}
@@ -51,24 +51,24 @@ ossimRpcPqeInputs::~ossimRpcPqeInputs()
//*****************************************************************************
ossimSensorModelTuple::ossimSensorModelTuple()
:
-theNumImages(0),
-theSurfCE90(0.0),
-theSurfLE90(0.0),
-theSurfAccSet(false),
-theSurfAccRepresentsNoDEM(false),
-theRpcPqeInputs()
+ theNumImages(0),
+ theSurfCE90(0.0),
+ theSurfLE90(0.0),
+ theSurfAccSet(false),
+ theSurfAccRepresentsNoDEM(false),
+ theRpcPqeInputs()
{
if (traceDebug())
{
ossimNotify(ossimNotifyLevel_DEBUG)
- << "\nossimSensorModelTuple::ossimSensorModelTuple DEBUG:"
- << std::endl;
+ << "\nossimSensorModelTuple::ossimSensorModelTuple DEBUG:"
+ << std::endl;
#ifdef OSSIM_ID_ENABLED
ossimNotify(ossimNotifyLevel_DEBUG)
- << "OSSIM_ID: " << OSSIM_ID << std::endl;
+ << "OSSIM_ID: " << OSSIM_ID << std::endl;
#endif
}
-
+
}
@@ -79,9 +79,9 @@ theRpcPqeInputs()
ossimSensorModelTuple::~ossimSensorModelTuple()
{
if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
- << "DEBUG: ~ossimSensorModelTuple(): entering..." << std::endl;
+ << "DEBUG: ~ossimSensorModelTuple(): entering..." << std::endl;
if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
- << "DEBUG: ~ossimSensorModelTuple(): returning..." << std::endl;
+ << "DEBUG: ~ossimSensorModelTuple(): returning..." << std::endl;
}
@@ -111,7 +111,7 @@ setIntersectionSurfaceAccuracy(const ossim_float64& surfCE90,
const ossim_float64& surfLE90)
{
bool setOK = false;
-
+
if (surfCE90>=0.0 && surfLE90>=0.0)
{
theSurfCE90 = surfCE90;
@@ -136,7 +136,7 @@ setIntersectionSurfaceAccuracy(const ossim_float64& surfCE90,
theSurfAccRepresentsNoDEM = true;
setOK = true;
}
-
+
return setOK;
}
@@ -192,30 +192,30 @@ intersect(const DptSet_t obs,
NEWMAT::ColumnVector dR(3);
NEWMAT::Matrix B(2,3);
NEWMAT::SymmetricMatrix W(2);
-
+
// Get a priori ground estimate using first point
ossimGpt estG;
- theImages[1]->lineSampleToWorld(obs[1], estG);
-
+ theImages[0]->lineSampleToWorld(obs[0], estG);
+
for (int iter=0; iter<5; iter++)
{
+ // cout<<"\n iter: "<<iter;
+
N = 0.0;
C = 0.0;
- // cout<<"\n Iter: "<<iter;
// Loop over observations
for (int i=0; i<nImages; i++)
{
ossimDpt resid;
- // if (!getGroundObsEqComponents(i, iter, obs[i], estG, resid, B, W))
if (!getGroundObsEqComponents(i, obs[i], estG, resid, B, W))
{
covOK = false;
}
-
+
F[0] = resid.x;
F[1] = resid.y;
- // cout<<"\n F{"<<i+1<<"}: "<<F[0]<<", "<<F[1];
+ // cout<<"\n F{"<<i+1<<"}: "<<F[0]<<", "<<F[1];
// Form coefficient matrix & discrepancy vector
BtWF << B.t() * W * F;
@@ -228,7 +228,7 @@ intersect(const DptSet_t obs,
Ni = invert(N);
dR = Ni * C;
- // cout<<"\n dR: ("<<dR[0]<<", "<<dR[1]<<", "<<dR[2]<<")"<<endl;
+ // cout<<"\n dR: ("<<dR[0]<<", "<<dR[1]<<", "<<dR[2]<<")"<<endl;
// Update estimate
double latUpd = estG.latd() - dR[0];
@@ -239,23 +239,22 @@ intersect(const DptSet_t obs,
estG.lond(lonUpd);
estG.height(hgtUpd);
-
if (traceDebug())
{
ossimNotify(ossimNotifyLevel_DEBUG)
- << "DEBUG: intersect:\n"
- << " iteration:\n" << iter
- // << " C:\n" << C
- // << " Ni:\n" << Ni
- << " dR:\n" << dR <<std::endl;
+ << "DEBUG: intersect:\n"
+ << " iteration:\n" << iter
+ // << " C:\n" << C
+ // << " Ni:\n" << Ni
+ << " dR:\n" << dR <<std::endl;
}
-
+
} // iterative loop
-
+
// Return intersected point
ossimEcefPoint finalEst(estG);
pt = finalEst;
-
+
// Return propagated covariance matrix
if (covOK)
{
@@ -264,14 +263,14 @@ intersect(const DptSet_t obs,
}
else
epOK = false;
-
+
// Set operation status
if (epOK)
opOK = OP_SUCCESS;
else
opOK = ERROR_PROP_FAIL;
}
-
+
return opOK;
}
@@ -291,21 +290,21 @@ intersect(const ossim_int32& img,
{
IntersectStatus opOK = OP_FAIL;
ossimGpt ptG;
-
+
// Intersection
theImages[img]->lineSampleHeightToWorld(obs, atHeightAboveEllipsoid, ptG);
ossimEcefPoint ptECF(ptG);
pt = ptECF;
-
+
// Error propagation
bool epOK = computeSingleInterCov(img, obs, ptG, AT_HGT, covMat);
-
+
// Set operation status
if (epOK)
opOK = OP_SUCCESS;
else
opOK = ERROR_PROP_FAIL;
-
+
return opOK;
}
@@ -319,26 +318,26 @@ intersect(const ossim_int32& img,
ossimSensorModelTuple::IntersectStatus ossimSensorModelTuple::
intersect(const ossim_int32& img,
const ossimDpt& obs,
- ossimEcefPoint& pt,
- NEWMAT::Matrix& covMat)
+ ossimEcefPoint& pt,
+ NEWMAT::Matrix& covMat)
{
IntersectStatus opOK = OP_FAIL;
ossimGpt ptG;
-
+
// Intersection
theImages[img]->lineSampleToWorld(obs, ptG);
ossimEcefPoint ptECF(ptG);
pt = ptECF;
-
+
// Error propagation
bool epOK = computeSingleInterCov(img, obs, ptG, AT_DEM, covMat);
-
+
// Set operation status
if (epOK)
opOK = OP_SUCCESS;
else
opOK = ERROR_PROP_FAIL;
-
+
return opOK;
}
@@ -358,7 +357,7 @@ bool ossimSensorModelTuple::getGroundObsEqComponents(
NEWMAT::SymmetricMatrix& W) const
{
// Temporary image geometry
- ossimImageGeometry* iGeom = new ossimImageGeometry(NULL, theImages[img]);
+ ossimImageGeometry* iGeom = new ossimImageGeometry(NULL, (ossimProjection*) theImages[img].get());
// Evaluate residuals
ossimDpt computedImg;
@@ -386,11 +385,11 @@ bool ossimSensorModelTuple::getGroundObsEqComponents(
NEWMAT::Matrix Wfull = invert(Cov);
W << Wfull;
}
-
+
bool covOK = false;
if (covStatus == ossimSensorModel::COV_FULL)
covOK = true;
-
+
return covOK;
}
@@ -413,28 +412,28 @@ bool ossimSensorModelTuple::computeSingleInterCov(
NEWMAT::SymmetricMatrix W(2);
NEWMAT::Matrix surfCovENU(3,3);
ossimDpt resid;
-
+
bool tCovOK;
bool covOK;
-
+
// Set the height reference
ossimHgtRef hgtRef(cRefType);
if (PTR_CAST(ossimRpcModel, theImages[img]))
{
- ossimRpcModel* model = PTR_CAST(ossimRpcModel, theImages[img]);
+ ossimRpcModel* model = PTR_CAST(ossimRpcModel, theImages[img]);
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Special case for handling RPC LOS error components
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // Special case for handling RPC LOS error components
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ossimGpt ptObs(obs.samp,obs.line);
theImages[img]->getForwardDeriv(OBS_INIT, ptObs);
resid = theImages[img]->getForwardDeriv(EVALUATE, ptG);
ossimDpt pWRTx = theImages[img]->getForwardDeriv(P_WRT_X, ptG);
ossimDpt pWRTy = theImages[img]->getForwardDeriv(P_WRT_Y, ptG);
ossimDpt pWRTz = theImages[img]->getForwardDeriv(P_WRT_Z, ptG);
-
+
// Form required partials in local frame
ossimLsrSpace enu(ptG);
NEWMAT::Matrix jECF(3,2);
@@ -452,7 +451,7 @@ bool ossimSensorModelTuple::computeSingleInterCov(
ossim_float64 dV_dx = jLSR(1,2);
ossim_float64 dV_dy = jLSR(2,2);
ossim_float64 dV_dz = jLSR(3,2);
-
+
// Compute azimuth & elevation angles
ossim_float64 den = dU_dy*dV_dx - dV_dy*dU_dx;
ossim_float64 dY = dU_dx*dV_dz - dV_dx*dU_dz;
@@ -473,7 +472,7 @@ bool ossimSensorModelTuple::computeSingleInterCov(
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ossim_float64 surfCE;
ossim_float64 surfLE;
-
+
if (theSurfAccRepresentsNoDEM)
{
//***************************************************************
@@ -483,10 +482,10 @@ bool ossimSensorModelTuple::computeSingleInterCov(
// [2] surfLE90 contains the probability level divisor for
// RPC hgtScale to yield a 1-sigma value
//***************************************************************
-
+
// Reset the surface normal to vertical
surfN = surfN.zAligned();
-
+
// Set approximate surface CE/LE based on RPC parameters
// [1] Assume range (scale) only to be 90% vertical error for now
// [2] Assume bias could be used for height
@@ -497,23 +496,23 @@ bool ossimSensorModelTuple::computeSingleInterCov(
ossim_float64 scaledHgtRng = abs(hgtRng/theSurfCE90);
ossim_float64 scaled1SigmaHgtRng = abs(scaledHgtRng/theSurfLE90);
surfLE = scaled1SigmaHgtRng*1.6449;
-
+
if(traceDebug())
{
ossimNotify(ossimNotifyLevel_INFO)
- << "\n computeSingleInterCov() RPC NoDEM state selected..."
- << "\n RPC Height Scale = " << rpcPar.hgtScale <<" m"
- << "\n Scale Divisor = " <<abs(theSurfCE90)
- << "\n 1-Sigma Divisor = "<<abs(theSurfLE90)
- << std::endl;
- }
- }
+ << "\n computeSingleInterCov() RPC NoDEM state selected..."
+ << "\n RPC Height Scale = " << rpcPar.hgtScale <<" m"
+ << "\n Scale Divisor = " <<abs(theSurfCE90)
+ << "\n 1-Sigma Divisor = "<<abs(theSurfLE90)
+ << std::endl;
+ }
+ }
else
{
surfCE = theSurfCE90;
surfLE = theSurfLE90;
}
-
+
tCovOK = hgtRef.getSurfaceCovMatrix(surfCE, surfLE, surfCovENU);
// Evaluate & retrieve the ENU covariance matrix
@@ -526,25 +525,25 @@ bool ossimSensorModelTuple::computeSingleInterCov(
theRpcPqeInputs.theRpcRandError = model->getRandError();
theRpcPqeInputs.theSurfaceNormalVector = surfN;
theRpcPqeInputs.theSurfaceCovMatrix = surfCovENU;
-
- if(traceDebug())
- {
- ossimNotify(ossimNotifyLevel_INFO)
- << "\n RPC error prop parameters..."
- << "\n Elevation Angle = " << tEl*DEG_PER_RAD<< " deg"
- << "\n Azimuth Angle = " << tAz*DEG_PER_RAD<<" deg"
- << "\n RPC Bias Error = " <<model->getBiasError() <<" m"
- << "\n RPC Random Error = " <<model->getRandError()<<" m"
- << "\n surfN = " <<surfN
- << "\n surfCovENU = \n" <<surfCovENU
- << std::endl;
- }
+
+ if(traceDebug())
+ {
+ ossimNotify(ossimNotifyLevel_INFO)
+ << "\n RPC error prop parameters..."
+ << "\n Elevation Angle = " << tEl*DEG_PER_RAD<< " deg"
+ << "\n Azimuth Angle = " << tAz*DEG_PER_RAD<<" deg"
+ << "\n RPC Bias Error = " <<model->getBiasError() <<" m"
+ << "\n RPC Random Error = " <<model->getRandError()<<" m"
+ << "\n surfN = " <<surfN
+ << "\n surfCovENU = \n" <<surfCovENU
+ << std::endl;
+ }
ossimEcefPoint pt(ptG);
-
+
ossimPositionQualityEvaluator qev
- (pt,model->getBiasError(),model->getRandError(),
- tEl,tAz,surfN,surfCovENU);
+ (pt,model->getBiasError(),model->getRandError(),
+ tEl,tAz,surfN,surfCovENU);
NEWMAT::Matrix covENU(3,3);
covOK = qev.getCovMatrix(covENU);
@@ -559,7 +558,7 @@ bool ossimSensorModelTuple::computeSingleInterCov(
covOK = false;
}
}
-
+
else
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -577,18 +576,18 @@ bool ossimSensorModelTuple::computeSingleInterCov(
// is fully supported, the following call should be used.
// hgtRef.getHeightCovMatrix(ptG, St);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+
// Check for special case of "no DEM" error propagation, only used for RPC
if (theSurfAccRepresentsNoDEM)
{
if(traceDebug())
{
ossimNotify(ossimNotifyLevel_INFO)
- << "\n computeSingleInterCov() RPC NoDEM state selected..."
- << " Not valid for this sensor model" << std::endl;
+ << "\n computeSingleInterCov() RPC NoDEM state selected..."
+ << " Not valid for this sensor model" << std::endl;
}
}
-
+
if (hgtRef.getSurfaceCovMatrix(theSurfCE90, theSurfLE90, surfCovENU))
{
tCovOK = hgtRef.getSurfaceNormalCovMatrix(ptG, surfCovENU, St);
@@ -597,7 +596,7 @@ bool ossimSensorModelTuple::computeSingleInterCov(
{
tCovOK = false;
}
-
+
if (tCovOK)
{
NEWMAT::Matrix Sti = invert(St);
@@ -610,7 +609,7 @@ bool ossimSensorModelTuple::computeSingleInterCov(
covMat = invert(BtWB);
}
}
-
+
return covOK;
}
@@ -630,7 +629,7 @@ NEWMAT::Matrix ossimSensorModelTuple::invert(const NEWMAT::Matrix& m) const
// decompose m.t*m into the singular values and vectors.
NEWMAT::SVD(m, d, u, v, true, true);
-
+
// invert the diagonal
for(idx=0; idx < (ossim_uint32)d.Ncols(); ++idx)
{
@@ -644,9 +643,9 @@ NEWMAT::Matrix ossimSensorModelTuple::invert(const NEWMAT::Matrix& m) const
if (traceDebug())
{
ossimNotify(ossimNotifyLevel_WARN)
- << "DEBUG: ossimSensorModelTuple::invert(): "
- << "\nsingular matrix in SVD..."
- << std::endl;
+ << "DEBUG: ossimSensorModelTuple::invert(): "
+ << "\nsingular matrix in SVD..."
+ << std::endl;
}
}
}
diff --git a/src/reg/GroundControlPoint.cpp b/src/reg/GroundControlPoint.cpp
new file mode 100644
index 0000000..48cee88
--- /dev/null
+++ b/src/reg/GroundControlPoint.cpp
@@ -0,0 +1,121 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#include <ossim/reg/GroundControlPoint.h>
+#include <ossim/base/ossimException.h>
+#include <ossim/base/ossimGpt.h>
+
+namespace ossim
+{
+
+GroundControlPoint::GroundControlPoint()
+{
+
+}
+
+GroundControlPoint::GroundControlPoint(const Json::Value& json_node)
+: m_covariance (3)
+{
+ m_covariance.ReSize(3);
+ loadJSON(json_node);
+}
+
+
+GroundControlPoint::~GroundControlPoint()
+{
+
+}
+
+void GroundControlPoint::loadJSON(const Json::Value& json_node)
+{
+ ostringstream xmsg;
+ xmsg<<__FILE__<<": ";
+
+ m_id = json_node["gcpId"].asString();
+ if (m_id.empty())
+ m_id = json_node["pointId"].asString();
+
+ if (json_node.isMember("lat") && json_node.isMember("lon") && json_node.isMember("hgt"))
+ {
+ ossimGpt refGpt;
+ refGpt.lat = json_node["lat"].asDouble();
+ refGpt.lon = json_node["lon"].asDouble();
+ refGpt.hgt = json_node["hgt"].asDouble();
+ m_gcp = ossimEcefPoint(refGpt);
+ }
+ else if (json_node.isMember("x") && json_node.isMember("y") && json_node.isMember("z"))
+ {
+ m_gcp.x() = json_node["x"].asDouble();
+ m_gcp.y() = json_node["y"].asDouble();
+ m_gcp.z() = json_node["z"].asDouble();
+ }
+ else
+ {
+ xmsg<<"Ground point coordinates JSON not correct. JSON: \n"<<json_node.toStyledString()<<endl;
+ throw ossimException(xmsg.str());
+ }
+
+ const Json::Value& covariance = json_node["covariance"];
+ unsigned int covSize = covariance.size();
+ if ((covSize != 6) || (covSize != 9))
+ {
+ xmsg<<"No covariance information in JSON or not correctly formatted (must be 6 or 9 element array)";
+ throw ossimException(xmsg.str());
+ }
+
+ // TODO: Covariance in proper coordinate system. ENU -> ECF conversion needed here?
+ if (covSize == 6)
+ {
+ m_covariance(0,0) = covariance[0].asDouble();
+ m_covariance(1,1) = covariance[1].asDouble();
+ m_covariance(2,2) = covariance[2].asDouble();
+ m_covariance(0,1) = covariance[3].asDouble();
+ m_covariance(0,2) = covariance[4].asDouble();
+ m_covariance(1,2) = covariance[5].asDouble();
+ }
+ else
+ {
+ m_covariance(0,0) = covariance[0].asDouble();
+ m_covariance(0,1) = covariance[1].asDouble();
+ m_covariance(0,2) = covariance[2].asDouble();
+ m_covariance(1,0) = covariance[3].asDouble();
+ m_covariance(1,1) = covariance[4].asDouble();
+ m_covariance(1,2) = covariance[5].asDouble();
+ m_covariance(2,0) = covariance[6].asDouble();
+ m_covariance(2,1) = covariance[7].asDouble();
+ m_covariance(2,2) = covariance[8].asDouble();
+ }
+
+ // TODO: Implement GCP cross-correlation
+ if (json_node.isMember("crossCovariances") || json_node.isMember("gpCrossCovList"))
+ {
+ ossimNotify(ossimNotifyLevel_WARN)<<"GCP cross covariances are specified in the JSON, but the"
+ " capability is not yet implemented!"<<endl;
+ }
+}
+
+void GroundControlPoint::saveJSON(Json::Value& json_node) const
+{
+ // ID
+ json_node["gcpId"] = m_id;
+
+ // ECF
+ json_node["X"] = m_gcp.x();
+ json_node["Y"] = m_gcp.y();
+ json_node["Z"] = m_gcp.z();
+
+ Json::Value covJson (Json::arrayValue);
+ covJson[0] = m_covariance(1,1);
+ covJson[1] = m_covariance(2,2);
+ covJson[2] = m_covariance(3,3);
+ covJson[3] = m_covariance(1,2);
+ covJson[4] = m_covariance(1,3);
+ covJson[5] = m_covariance(2,3);
+
+ json_node["covariance"] = covJson;
+}
+} // end namespace ossimMsp
diff --git a/src/reg/Image.cpp b/src/reg/Image.cpp
new file mode 100644
index 0000000..6fa6ad1
--- /dev/null
+++ b/src/reg/Image.cpp
@@ -0,0 +1,115 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#include <ossim/reg/Image.h>
+#include <ossim/base/ossimException.h>
+#include <ossim/base/ossimString.h>
+#include <ossim/projection/ossimProjectionFactoryRegistry.h>
+
+using namespace std;
+
+namespace ossim
+{
+
+Image::Image(const std::string& imageId,
+ const std::string& filename,
+ const std::string& modelName,
+ unsigned int entryIndex,
+ unsigned int band)
+: m_imageId (imageId),
+ m_filename (filename),
+ m_entryIndex (entryIndex),
+ m_activeBand (band),
+ m_modelName (modelName)
+{
+
+}
+
+Image::Image(const Json::Value& json_node)
+: m_entryIndex (0)
+{
+ loadJSON(json_node);
+}
+
+Image::~Image()
+{
+ //m_handler.reset();
+}
+
+void Image::getAvailableModels(std::vector< pair<string, string> >& availableModels) const
+{
+ ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->
+ createProjection(m_filename, m_entryIndex);
+ if (proj)
+ {
+ availableModels.push_back(pair<string, string>("OSSIM", proj->getLongName().string()));
+ delete proj;
+ }
+}
+
+void Image::loadJSON(const Json::Value& json_node)
+{
+ ostringstream xmsg;
+ xmsg<<__FILE__<<": loadJSON(JSON) -- ";
+
+ // Parse JSON. Filename is required:
+ if (json_node.isMember("filename"))
+ {
+ ossimFilename imageFile = json_node["filename"].asString();
+ m_filename = imageFile.expand(); // allow embedded environment variables
+ }
+ else
+ {
+ xmsg<<"JSON node missing required field: \"filename\".";
+ throw ossimException(xmsg.str());
+ }
+
+ // Entry index defaults to 0 if not present:
+ if (json_node["entryIndex"].isUInt())
+ m_entryIndex = json_node["entryIndex"].asUInt();
+
+ // Band defaults to 1 if not present:
+ if (json_node["band"].isUInt())
+ m_activeBand = json_node["band"].asUInt();
+
+ // Sensor model defaults to most accurate available if not provided (indicated by blank name):
+ if (json_node.isMember("sensorModel"))
+ m_modelName = json_node["sensorModel"].asString();
+
+ // Sensor model defaults to most accurate available if not provided (indicated by blank name):
+ if (json_node.isMember("imageId"))
+ m_imageId = json_node["imageId"].asString();
+
+ // Establish the sensor model. This also sets the official image ID, which will be overwritten
+ // if JSON field provided
+ string modelState = json_node["modelState"].asString();
+ ossimKeywordlist kwl;
+ kwl.parseString(modelState);
+ ossimProjection* proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
+ m_sensorModel = dynamic_cast<ossimSensorModel*>(proj);
+}
+
+void Image::saveJSON(Json::Value& json_node) const
+{
+ json_node.clear();
+ json_node["imageId"] = m_imageId;
+ json_node["filename"] = m_filename.string();
+ json_node["entryIndex"] = m_entryIndex;
+
+ if (m_modelName.size())
+ json_node["sensorModel"] = m_modelName;
+
+ if (m_sensorModel.valid())
+ {
+ ossimKeywordlist kwl;
+ m_sensorModel->saveState(kwl);
+ json_node["modelState"] = kwl.toString().string();
+ }
+}
+
+
+} // end namespace
diff --git a/src/reg/PhotoBlock.cpp b/src/reg/PhotoBlock.cpp
new file mode 100644
index 0000000..fc297c1
--- /dev/null
+++ b/src/reg/PhotoBlock.cpp
@@ -0,0 +1,183 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#include <ossim/reg/PhotoBlock.h>
+#include <ossim/base/ossimException.h>
+
+namespace ossim
+{
+PhotoBlock::PhotoBlock()
+{
+}
+
+PhotoBlock::PhotoBlock(const Json::Value& pb_json_node)
+{
+ loadJSON(pb_json_node);
+}
+
+PhotoBlock::PhotoBlock(const PhotoBlock& copyThis)
+: m_imageList (copyThis.m_imageList),
+ m_tiePointList (copyThis.m_tiePointList)
+{
+ *this = copyThis;
+}
+
+PhotoBlock::~PhotoBlock()
+{
+ m_imageList.clear();
+ m_tiePointList.clear();
+}
+
+PhotoBlock& PhotoBlock::operator=(const PhotoBlock& copythis)
+{
+ m_imageList = copythis.m_imageList;
+ m_tiePointList = copythis.m_tiePointList;
+ m_gcpList = copythis.m_gcpList;
+ return *this;
+}
+
+// TODO: Add of individual components not available until proper management of the JCM can be
+// provided
+unsigned int PhotoBlock::addImage(shared_ptr<Image> image)
+{
+ unsigned int last_idx = m_imageList.size();
+ m_imageList.push_back(image);
+ return last_idx;
+}
+
+unsigned int PhotoBlock::addGroundPoint(shared_ptr<GroundControlPoint> gcp)
+{
+ unsigned int last_idx = m_gcpList.size();
+ m_gcpList.push_back(gcp);
+ return last_idx;
+}
+
+unsigned int PhotoBlock::addTiePoint(shared_ptr<TiePoint> tiepoint)
+{
+ unsigned int index = m_tiePointList.size();
+ m_tiePointList.push_back(tiepoint);
+ return index;
+}
+
+void PhotoBlock::addTiePoints(TiePointList& tiepointList)
+{
+ for (size_t i=0; i<tiepointList.size(); ++i)
+ {
+ addTiePoint(tiepointList[i]);
+ }
+}
+
+shared_ptr<Image> PhotoBlock::getImage(const std::string& imageId)
+{
+ std::shared_ptr<Image> result;
+ for (size_t i=0; i<m_imageList.size(); ++i)
+ {
+ if (m_imageList[i]->getImageId() == imageId)
+ {
+ result = m_imageList[i];
+ break;
+ }
+ }
+ return result;
+}
+
+shared_ptr<GroundControlPoint> PhotoBlock::getGroundPoint(const std::string& gcpId)
+{
+ std::shared_ptr<GroundControlPoint> result;
+ for (size_t i=0; i<m_gcpList.size(); ++i)
+ {
+ if (m_gcpList[i]->getId() == gcpId)
+ {
+ result = m_gcpList[i];
+ break;
+ }
+ }
+ return result;
+}
+
+shared_ptr<TiePoint> PhotoBlock::getTiePoint(unsigned int tpId)
+{
+ std::shared_ptr<TiePoint> result;
+ for (size_t i=0; i<m_tiePointList.size(); ++i)
+ {
+ if (m_tiePointList[i]->getTiePointId() == tpId)
+ {
+ result = m_tiePointList[i];
+ break;
+ }
+ }
+ return result;
+}
+
+void PhotoBlock::loadJSON(const Json::Value& pb_json_node)
+{
+ // Always do images first, as tiepoints will be using the image list to correct image ID:
+ if (pb_json_node.isMember("images"))
+ {
+ const Json::Value& listJson = pb_json_node["images"];
+ unsigned int count = listJson.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ const Json::Value& jsonItem = listJson[i];
+ shared_ptr<Image> item (new Image(jsonItem));
+ m_imageList.push_back(item);
+ }
+ }
+
+ if (pb_json_node.isMember("groundPoints"))
+ {
+ const Json::Value& listJson = pb_json_node["groundPoints"];
+ unsigned int count = listJson.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ const Json::Value& jsonItem = listJson[i];
+ shared_ptr<GroundControlPoint> item (new GroundControlPoint(jsonItem));
+ m_gcpList.push_back(item);
+ }
+ }
+
+ if (pb_json_node.isMember("tiePoints"))
+ {
+ const Json::Value& listJson = pb_json_node["tiePoints"];
+ unsigned int count = listJson.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ const Json::Value& jsonItem = listJson[i];
+ shared_ptr<TiePoint> item (new TiePoint(jsonItem));
+ m_tiePointList.push_back(item);
+ }
+ }
+}
+
+void PhotoBlock::saveJSON(Json::Value& pbJSON) const
+{
+ Json::Value imageListJson (Json::arrayValue);
+ unsigned int count = m_imageList.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ m_imageList[i]->saveJSON(imageListJson[i]);
+ }
+ pbJSON["images"] = imageListJson;
+
+ Json::Value gcpListJson (Json::arrayValue);
+ count = m_gcpList.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ m_gcpList[i]->saveJSON(gcpListJson[i]);
+ }
+ pbJSON["groundPoints"] = gcpListJson;
+
+ Json::Value tpListJson (Json::arrayValue);
+ count = m_tiePointList.size();
+ for (unsigned int i=0; i<count; ++i)
+ {
+ m_tiePointList[i]->saveJSON(tpListJson[i]);
+ }
+ pbJSON["tiePoints"] = tpListJson;
+}
+
+} // end namespace
diff --git a/src/reg/TiePoint.cpp b/src/reg/TiePoint.cpp
new file mode 100644
index 0000000..8b0a885
--- /dev/null
+++ b/src/reg/TiePoint.cpp
@@ -0,0 +1,243 @@
+//**************************************************************************************************
+//
+// OSSIM Open Source Geospatial Data Processing Library
+// See top level LICENSE.txt file for license information
+//
+//**************************************************************************************************
+
+#include <ossim/reg/TiePoint.h>
+#include <ossim/base/ossimException.h>
+#include <ctime>
+
+using namespace std;
+
+namespace ossim
+{
+int TiePoint::s_runningId = 1;
+
+TiePoint::TiePoint()
+: m_type (UNASSIGNED),
+ m_gsd (0.0)
+{
+
+}
+
+TiePoint::TiePoint(const TiePoint& copy)
+: m_type (copy.m_type),
+ m_gsd (copy.m_gsd),
+ m_gcpId (copy.m_gcpId)
+{
+ for (size_t i=0; i<copy.m_images.size(); ++i)
+ m_images.push_back(copy.m_images[i]);
+
+ for (size_t i=0; i<copy.m_imagePoints.size(); ++i)
+ m_imagePoints.push_back(copy.m_imagePoints[i]);
+
+ for (size_t i=0; i<copy.m_covariances.size(); ++i)
+ m_covariances.push_back(copy.m_covariances[i]);
+}
+
+TiePoint::TiePoint(const Json::Value& json_node)
+: m_type (UNASSIGNED),
+ m_gsd (0.0)
+{
+ loadJSON(json_node);
+}
+
+TiePoint::~TiePoint()
+{
+ m_images.clear();
+ m_imagePoints.clear();
+ m_covariances.clear();
+}
+
+void TiePoint::setTiePointId(const string& id)
+{
+ if (id.empty())
+ {
+ // Generate ID based on date/time:
+ ostringstream tp1;
+ tp1<<"TP"<<s_runningId++;
+ m_tiePointId = tp1.str();
+ }
+ else
+ {
+ // Only accept if there is no ID existing:
+ m_tiePointId = id;
+ }
+}
+
+void TiePoint::getImagePoint(unsigned int index,
+ std::string& imageId,
+ ossimDpt& imagePoint,
+ NEWMAT::SymmetricMatrix& cov) const
+{
+ // Search the PB index list for entry:
+ imagePoint.makeNan();
+ imageId.clear();
+
+ if (index >= m_images.size())
+ return;
+
+ imageId = m_images[index]->getImageId();
+ imagePoint = m_imagePoints[index];
+ cov = m_covariances[index];
+}
+
+void TiePoint::setImagePoint(std::shared_ptr<Image> image,
+ const ossimDpt& imagePoint,
+ const NEWMAT::SymmetricMatrix& cov)
+{
+ bool found = false;
+
+ // Possible edit of existing point?
+ for (size_t i=0; i<m_images.size(); ++i)
+ {
+ if (m_images[i]->getImageId().compare(image->getImageId()) == 0)
+ {
+ found = true;
+ if (i >= m_imagePoints.size())
+ {
+ // This shouldn't happen, but go ahead and resize for this image:
+ m_imagePoints.resize(i+1);
+ m_covariances.resize(i+1);
+ }
+ m_imagePoints[i] = imagePoint;
+ m_covariances[i] = cov;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ m_images.push_back(image);
+ m_imagePoints.push_back(imagePoint);
+ m_covariances.push_back(cov);
+ }
+}
+
+void TiePoint::setGcpId(const std::string& id)
+{
+ m_gcpId = id;
+ m_type = GCP;
+}
+
+void TiePoint::loadJSON(const Json::Value& json_node)
+{
+ ostringstream xmsg;
+ xmsg<<__FILE__<<": TiePoint(JSON) --";
+
+ // ID
+ setTiePointId(json_node["id"].asString());
+
+ // Type
+ string tpType = json_node["type"].asString();
+ switch (tpType[0])
+ {
+ case 'M':
+ m_type = TiePoint::MANUAL;
+ break;
+ case 'A':
+ m_type = TiePoint::AUTO;
+ break;
+ case 'G':
+ m_type = TiePoint::GCP;
+ break;
+ default:
+ xmsg<<"Tiepoint JSON field \"type\" must be specified as 'M', 'A', or 'G'.";
+ throw ossimException(xmsg.str());
+ }
+
+ // Read the GCP ID if present:
+ if (m_type == TiePoint::GCP)
+ m_gcpId = json_node["gcpId"].asString();
+
+ // Image points
+ const Json::Value& imagePoints = json_node["imagePoints"];
+ if (!imagePoints || (imagePoints.size() < 1))
+ {
+ xmsg<<"Tiepoint JSON field \"imagePoints\" not found or is empty!";
+ throw ossimException(xmsg.str());
+ }
+
+ // Loop over points on each image:
+ for (int i=0; i<imagePoints.size(); ++i)
+ {
+ const Json::Value& p = imagePoints[i];
+ if (!p || !(p["imageId"].isString()) || !(p["x"]) || !(p["y"]) || (p["covariance"].size()!=3))
+ {
+ xmsg<<"Tiepoint JSON field \"imagePoints\" entry is ill-formed or not complete:\n"
+ <<p.toStyledString()<<endl;
+ throw ossimException(xmsg.str());
+ }
+
+ string imageId = p["imageId"].asString();
+ string filename = p["filename"].asString();
+ shared_ptr<Image> image (new Image(imageId, filename));
+ m_images.push_back(image);
+
+ ossimDpt xy(p["x"].asDouble(), p["y"].asDouble());
+ m_imagePoints.push_back(xy);
+
+ const Json::Value& covariance = p["covariance"];
+ NEWMAT::SymmetricMatrix c (2);
+ c(1,1) = covariance[0].asDouble();
+ c(2,2) = covariance[1].asDouble();
+ c(1,2) = covariance[2].asDouble();
+ m_covariances.push_back(c);
+ }
+}
+
+void TiePoint::saveJSON(Json::Value& json_node) const
+{
+ // ID
+ json_node["id"] = m_tiePointId;
+
+ // Type
+ string tpType = json_node["type"].asString();
+ switch (m_type)
+ {
+ case TiePoint::MANUAL:
+ json_node["type"] = "M";
+ break;
+ case TiePoint::AUTO:
+ json_node["type"] = "A";
+ break;
+ case TiePoint::GCP:
+ json_node["type"] = "G";
+ break;
+ default:
+ json_node["type"] = "UNNASSIGNED";
+ }
+
+ // Image points
+ Json::Value jsonList (Json::arrayValue);
+ // Loop over points on each image:
+ for (int i=0; i<m_imagePoints.size(); ++i)
+ {
+ jsonList[i]["filename"] = m_images[i]->getFilename();
+ jsonList[i]["imageId"] = m_images[i]->getImageId();
+ jsonList[i]["x"] = m_imagePoints[i].x;
+ jsonList[i]["y"] = m_imagePoints[i].y;
+
+ if (i<m_covariances.size())
+ {
+ Json::Value covJson (Json::arrayValue);
+ covJson[0] = m_covariances[i](1,1);
+ covJson[1] = m_covariances[i](2,2);
+ covJson[2] = m_covariances[i](1,2);
+ jsonList[i]["covariance"] = covJson;
+ }
+ }
+ json_node["imagePoints"] = jsonList;
+}
+
+std::ostream& TiePoint::print(std::ostream& out) const
+{
+ Json::Value node;
+ saveJSON(node);
+ out << node.toStyledString();
+ return out;
+}
+
+} // end namespace ISA
diff --git a/src/support_data/ossimQuickbirdRpcHeader.cpp b/src/support_data/ossimQuickbirdRpcHeader.cpp
index 69fefb4..24fdcc3 100644
--- a/src/support_data/ossimQuickbirdRpcHeader.cpp
+++ b/src/support_data/ossimQuickbirdRpcHeader.cpp
@@ -53,6 +53,18 @@ std::ostream& operator << (std::ostream& out,
ossimQuickbirdRpcHeader::ossimQuickbirdRpcHeader()
+: theErrBias(0),
+ theErrRand(0),
+ theLineOffset(0),
+ theSampOffset(0),
+ theLatOffset(0),
+ theLonOffset(0),
+ theHeightOffset(0),
+ theLineScale(0),
+ theSampScale(0),
+ theLatScale(0),
+ theLonScale(0),
+ theHeightScale(0)
{
}
diff --git a/src/util/ossimTool.cpp b/src/util/ossimTool.cpp
index d531462..c081b95 100644
--- a/src/util/ossimTool.cpp
+++ b/src/util/ossimTool.cpp
@@ -97,11 +97,6 @@ void ossimTool::initialize(const ossimKeywordlist& kwl)
m_kwl = kwl;
}
-void ossimTool::initialize(const std::string& request)
-{
- m_helpRequested = false;
-}
-
void ossimTool::getKwlTemplate(ossimKeywordlist& kwl)
{
ossimFilename share_dir = ossimPreferences::instance()->
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/ossim.git
More information about the Pkg-grass-devel
mailing list