<commit_before>#pragma once
#include "math_util.hpp"
#include <boost/assert.hpp>
#include <boost/operators.hpp>
#include <cmath>
#include <limits>
#include <numeric>

namespace dmc
{
	template <class Scalar, int Dimension>
	class vector;

	template <class Derived, class Scalar, int Dimension>
	class vector_base
		: boost::addable<
			  Derived,
			  boost::subtractable<
				  Derived,
				  boost::multipliable<
					  Derived,
					  Scalar,
					  boost::dividable<
						  Derived,
						  Scalar,
						  boost::equality_comparable<
							  Derived>>>>>
	{
	public:
		typedef Scalar scalar_type;
		static const int dimension = Dimension;

		scalar_type* data()
		{
			return &values_[0];
		}

		const scalar_type* data() const
		{
			return &values_[0];
		}

		scalar_type& operator[](int index)
		{
			BOOST_ASSERT(0 <= index && index < dimension);
			return values_[index];
		}

		scalar_type operator[](int index) const
		{
			BOOST_ASSERT(0 <= index && index < dimension);
			return values_[index];
		}

		Derived operator-() const
		{
			return map([](auto x) { return -x; });
		}

		const Derived& operator+() const
		{
			return derived();
		}

		Derived& operator+=(const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] += rhs[i];
			return derived();
		}

		Derived& operator-=(const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] -= rhs[i];
			return derived();
		}

		Derived& operator*=(scalar_type rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] *= rhs;
			return derived();
		}

		Derived& operator/=(scalar_type rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] /= rhs;
			return derived();
		}

		template <class F>
		vector<typename std::result_of<F(scalar_type)>::type, dimension> map(F f) const
		{
			vector<typename std::result_of<F(scalar_type)>::type, dimension> result;
			for (int i = 0; i < dimension; ++i)
				result[i] = f((*this)[i]);
			return result;
		}

		template <class T>
		auto cast() const
		{
			return map([](auto x) { return static_cast<T>(x); });
		}

		auto sign() const
		{
			return map([](auto x) { return dmc::sign(x); });
		}

		template <class T, class F>
		auto reduce(T t, F f) const
		{
			for (int i = 0; i < dimension; ++i)
				t = f(t, (*this)[i]);
			return t;
		}

		template <class F>
		auto reduce(F f) const
		{
			auto t = (*this)[0];
			for (int i = 1; i < dimension; ++i)
				t = f(t, (*this)[i]);
			return t;
		}

		auto sum() const
		{
			return reduce([](auto x, auto y) {
				return x + y;
			});
		}

		auto product() const
		{
			return reduce([](auto x, auto y) {
				return x * y;
			});
		}

		auto abs() const
		{
			return map([](auto x) { using std::abs; return abs(x); });
		}

		auto norm_l1() const
		{
			return abs().sum();
		}

		auto squared() const
		{
			return map([](auto x) { return squared(x); });
		}

		auto norm_l2_sq() const
		{
			return squared().sum();
		}

		auto norm_l2() const
		{
			using std::sqrt;
			return sqrt(norm_l2_sq());
		}

		auto max() const
		{
			return reduce([](auto x, auto y) { using std::max; return max(x, y); });
		}

		auto min() const
		{
			return reduce([](auto x, auto y) { using std::min; return min(x, y); });
		}

		bool try_normalize()
		{
			auto n = norm_l2();
			if (n < std::numeric_limits<scalar_type>::epsilon())
				return false;

			*this /= n;
			return true;
		}

		Derived clamp(const Derived& minimum, const Derived& maximum)
		{
			Derived result;
			for (int i = 0; i < dimension; ++i)
				result[i] = std::max(minimum[i], std::min(maximum[i], (*this)[i]));
			return result;
		}

		static Derived all(scalar_type s)
		{
			Derived result;
			for (int i = 0; i < dimension; ++i)
				result[i] = s;
			return result;
		}

		friend bool operator==(const Derived& lhs, const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				if (lhs[i] != rhs[i])
					return false;

			return true;
		}

	private:
		Derived& derived()
		{
			return static_cast<Derived&>(*this);
		}

		const Derived& derived() const
		{
			return static_cast<const Derived&>(*this);
		}

		scalar_type values_[dimension] = {};
	};
}
<commit_msg>Fix vector_base<commit_after>#pragma once
#include "math_util.hpp"
#include <boost/assert.hpp>
#include <boost/operators.hpp>
#include <cmath>
#include <limits>
#include <numeric>

namespace dmc
{
	template <class Scalar, int Dimension>
	class vector;

	template <class Derived, class Scalar, int Dimension>
	class vector_base
		: boost::addable<
			  Derived,
			  boost::subtractable<
				  Derived,
				  boost::multipliable<
					  Derived,
					  Scalar,
					  boost::dividable<
						  Derived,
						  Scalar,
						  boost::equality_comparable<
							  Derived>>>>>
	{
	public:
		typedef Scalar scalar_type;
		static const int dimension = Dimension;

		scalar_type* data()
		{
			return &values_[0];
		}

		const scalar_type* data() const
		{
			return &values_[0];
		}

		scalar_type& operator[](int index)
		{
			BOOST_ASSERT(0 <= index && index < dimension);
			return values_[index];
		}

		scalar_type operator[](int index) const
		{
			BOOST_ASSERT(0 <= index && index < dimension);
			return values_[index];
		}

		Derived operator-() const
		{
			return map([](auto x) { return -x; });
		}

		const Derived& operator+() const
		{
			return derived();
		}

		Derived& operator+=(const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] += rhs[i];
			return derived();
		}

		Derived& operator-=(const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] -= rhs[i];
			return derived();
		}

		Derived& operator*=(scalar_type rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] *= rhs;
			return derived();
		}

		Derived& operator/=(scalar_type rhs)
		{
			for (int i = 0; i < dimension; ++i)
				(*this)[i] /= rhs;
			return derived();
		}

		template <class F>
		vector<typename std::result_of<F(scalar_type)>::type, dimension> map(F f) const
		{
			vector<typename std::result_of<F(scalar_type)>::type, dimension> result;
			for (int i = 0; i < dimension; ++i)
				result[i] = f((*this)[i]);
			return result;
		}

		template <class T>
		auto cast() const
		{
			return map([](auto x) { return static_cast<T>(x); });
		}

		auto sign() const
		{
			return map([](auto x) { return dmc::sign(x); });
		}

		template <class T, class F>
		auto reduce(T t, F f) const
		{
			for (int i = 0; i < dimension; ++i)
				t = f(t, (*this)[i]);
			return t;
		}

		template <class F>
		auto reduce(F f) const
		{
			auto t = (*this)[0];
			for (int i = 1; i < dimension; ++i)
				t = f(t, (*this)[i]);
			return t;
		}

		auto sum() const
		{
			return reduce([](auto x, auto y) {
				return x + y;
			});
		}

		auto product() const
		{
			return reduce([](auto x, auto y) {
				return x * y;
			});
		}

		auto abs() const
		{
			return map([](auto x) { using std::abs; return abs(x); });
		}

		auto norm_l1() const
		{
			return abs().sum();
		}

		auto squared() const
		{
			return map([this](auto x) { return x * x; });
		}

		auto norm_l2_sq() const
		{
			return squared().sum();
		}

		auto norm_l2() const
		{
			using std::sqrt;
			return sqrt(norm_l2_sq());
		}

		auto max() const
		{
			return reduce([](auto x, auto y) { using std::max; return max(x, y); });
		}

		auto min() const
		{
			return reduce([](auto x, auto y) { using std::min; return min(x, y); });
		}

		bool try_normalize()
		{
			auto n = norm_l2();
			if (n < std::numeric_limits<scalar_type>::epsilon())
				return false;

			*this /= n;
			return true;
		}

		Derived clamp(const Derived& minimum, const Derived& maximum)
		{
			Derived result;
			for (int i = 0; i < dimension; ++i)
				result[i] = std::max(minimum[i], std::min(maximum[i], (*this)[i]));
			return result;
		}

		static Derived all(scalar_type s)
		{
			Derived result;
			for (int i = 0; i < dimension; ++i)
				result[i] = s;
			return result;
		}

		friend bool operator==(const Derived& lhs, const Derived& rhs)
		{
			for (int i = 0; i < dimension; ++i)
				if (lhs[i] != rhs[i])
					return false;

			return true;
		}

	private:
		Derived& derived()
		{
			return static_cast<Derived&>(*this);
		}

		const Derived& derived() const
		{
			return static_cast<const Derived&>(*this);
		}

		scalar_type values_[dimension] = {};
	};
}
<|endoftext|>


<commit_before>#include "settings.hpp"

#include "capabilities.hpp"
#include "log.hpp"

#include <stdio.h>

namespace fcwt {

std::string to_string(iso_level iso) {
    auto const lvl = iso.value;
    char const* flag = "";

    // movie iso auto is  0xffffffff
    if (lvl == 0xffffffff)
        return "auto";

    if (lvl & iso_flag_auto)
        flag = "(auto)";
    else if (lvl & iso_flag_emulated)
        flag = "(emulated)";

    return string_format("%6d %s", lvl & iso_value_mask, flag);
}

char const* to_string(shutter_speed speed) {
    bool subsecond = bool(speed & shutter_flag_subsecond);
    double out = static_cast<double>(speed & shutter_value_mask) / 1000.0;
    if (subsecond)
        return string_format("1/%.1fs", out).c_str();
    else
        return string_format("%.1fs", out).c_str();
}

std::string to_string(auto_focus_point const& focus_point) {
  return string_format("(%d, %d)", focus_point.x, focus_point.y);
}

std::string to_string(f_number aperture) {
  if (aperture.value == 0xffff)
    return "---";
  else if (aperture)
    return string_format("%.1ff", static_cast<double>(aperture) / 100.0);
  else
    return "Auto";
}

double ss_to_microsec(uint32_t raw_speed) {
  /* convert shutter speed raw value (obtained from camera) to microseconds */
  if (raw_speed & shutter_flag_subsecond)
    return 1000.0 * (1000000.0 / static_cast<double>(raw_speed & shutter_value_mask));
  else
    return 1000.0 * static_cast<double>(raw_speed);
}

void print(std::map<property_codes, uint32_t> const& settings) {
    printf("camera settings:\n");

    for (auto const &s : settings) {
        auto const &key   = s.first;
        auto const &value = s.second;

        if (! property_strings.count(key)) {
            printf("\t%s (%s): %s\n", property_strings[property_unknown],
                   hex_format(&key, 2).c_str(), hex_format(&value, 4).c_str());
            continue;
        }

        printf("\t%s: ", property_strings[key]);
        if (key == property_iso || key == property_movie_iso) {
            iso_level const iso { value };
            printf("%s\n", to_string(iso).c_str());
        } else if (key == property_shutter_speed) {
            shutter_speed const spd { value };
            printf(" %s\n", to_string(spd));
        } else if (key == property_focus_point) {
            auto_focus_point point = value;
            printf("%s\n", to_string(point).c_str());
        } else if (key == property_aperture) {
            f_number aperture = value;
            printf("%s\n", to_string(aperture).c_str());
        } else if (key == property_exposure_compensation) {
            printf("%.1f\n", static_cast<double>(static_cast<int16_t>(value)) / 1000.0);
        } else if (key == property_movie_remaining_time || key == property_image_space_sd) {
            printf("%d\n", value);
        } else if (property_value_strings[key].count(value)) {
            printf("%s\n", property_value_strings[key][value]);
        } else {
            printf("%s\n", property_value_strings[property_unknown][0]);
        }
    }
}

}  // namespace fcwt
<commit_msg>Interpret -1 shutter speed value as "----" (outside metering range)<commit_after>#include "settings.hpp"

#include "capabilities.hpp"
#include "log.hpp"

#include <stdio.h>

namespace fcwt {

std::string to_string(iso_level iso) {
    auto const lvl = iso.value;
    char const* flag = "";

    // movie iso auto is  0xffffffff
    if (lvl == 0xffffffff)
        return "auto";

    if (lvl & iso_flag_auto)
        flag = "(auto)";
    else if (lvl & iso_flag_emulated)
        flag = "(emulated)";

    return string_format("%6d %s", lvl & iso_value_mask, flag);
}

char const* to_string(shutter_speed speed) {
    if (static_cast<int32_t>(speed.value) == -1)
        return "----";

    bool subsecond = bool(speed & shutter_flag_subsecond);
    double out = static_cast<double>(speed & shutter_value_mask) / 1000.0;
    if (subsecond)
        return string_format("1/%.1fs", out).c_str();
    else
        return string_format("%.1fs", out).c_str();
}

std::string to_string(auto_focus_point const& focus_point) {
  return string_format("(%d, %d)", focus_point.x, focus_point.y);
}

std::string to_string(f_number aperture) {
  if (aperture.value == 0xffff)
    return "---";
  else if (aperture)
    return string_format("%.1ff", static_cast<double>(aperture) / 100.0);
  else
    return "Auto";
}

double ss_to_microsec(uint32_t raw_speed) {
  /* convert shutter speed raw value (obtained from camera) to microseconds */
  if (raw_speed & shutter_flag_subsecond)
    return 1000.0 * (1000000.0 / static_cast<double>(raw_speed & shutter_value_mask));
  else
    return 1000.0 * static_cast<double>(raw_speed);
}

void print(std::map<property_codes, uint32_t> const& settings) {
    printf("camera settings:\n");

    for (auto const &s : settings) {
        auto const &key   = s.first;
        auto const &value = s.second;

        if (! property_strings.count(key)) {
            printf("\t%s (%s): %s\n", property_strings[property_unknown],
                   hex_format(&key, 2).c_str(), hex_format(&value, 4).c_str());
            continue;
        }

        printf("\t%s: ", property_strings[key]);
        if (key == property_iso || key == property_movie_iso) {
            iso_level const iso { value };
            printf("%s\n", to_string(iso).c_str());
        } else if (key == property_shutter_speed) {
            shutter_speed const spd { value };
            printf(" %s\n", to_string(spd));
        } else if (key == property_focus_point) {
            auto_focus_point point = value;
            printf("%s\n", to_string(point).c_str());
        } else if (key == property_aperture) {
            f_number aperture = value;
            printf("%s\n", to_string(aperture).c_str());
        } else if (key == property_exposure_compensation) {
            printf("%.1f\n", static_cast<double>(static_cast<int16_t>(value)) / 1000.0);
        } else if (key == property_movie_remaining_time || key == property_image_space_sd) {
            printf("%d\n", value);
        } else if (property_value_strings[key].count(value)) {
            printf("%s\n", property_value_strings[key][value]);
        } else {
            printf("%s\n", property_value_strings[property_unknown][0]);
        }
    }
}

}  // namespace fcwt
<|endoftext|>


<commit_before>#ifndef LIBREALSENSE_RS_HPP
#define LIBREALSENSE_RS_HPP

#include "rsutil.h"
#include <cstdint>
#include <sstream>

namespace rs
{

    enum class stream : int32_t
    {
        depth = 0, // Native stream of depth data produced by RealSense device
        color = 1, // Native stream of color data captured by RealSense device
        infrared = 2, // Native stream of infrared data captured by RealSense device
        infrared2 = 3, // Native stream of infrared data captured from a second viewpoint by RealSense device
        rectified_color = 4, // Synthetic stream containing undistorted color data with no extrinsic rotation from the depth stream
        color_aligned_to_depth = 5, // Synthetic stream containing color data but sharing intrinsics of depth stream
        depth_aligned_to_color = 6, // Synthetic stream containing depth data but sharing intrinsics of color stream
        depth_aligned_to_rectified_color = 7 // Synthetic stream containing depth data but sharing intrinsics of rectified color stream
    };

    enum class format : int32_t
    {
        any = 0,
        z16 = 1,
        yuyv = 2,
        rgb8 = 3,
        bgr8 = 4,
        rgba8 = 5,
        bgra8 = 6,
        y8 = 7,
        y16 = 8,
        raw10 = 9 // Four 10-bit luminance values encoded into a 5-byte macropixel
    };

    enum class preset : int32_t
    {
        best_quality = 0,
        largest_image = 1,
        highest_framerate = 2
    };

    enum class distortion : int32_t
    {
        none = 0, // Rectilinear images, no distortion compensation required
        modified_brown_conrady = 1, // Equivalent to Brown-Conrady distortion, except that tangential distortion is applied to radially distorted points
        inverse_brown_conrady = 2 // Equivalent to Brown-Conrady distortion, except undistorts image instead of distorting it
    };

    enum class option : int32_t
    {
        color_backlight_compensation = 0,
        color_brightness = 1,
        color_contrast = 2,
        color_exposure = 3,
        color_gain = 4,
        color_gamma = 5,
        color_hue = 6,
        color_saturation = 7,
        color_sharpness = 8,
        color_white_balance = 9,
        f200_laser_power = 10, // 0 - 15
        f200_accuracy = 11, // 0 - 3
        f200_motion_range = 12, // 0 - 100
        f200_filter_option = 13, // 0 - 7
        f200_confidence_threshold = 14, // 0 - 15
        f200_dynamic_fps = 15, // {2, 5, 15, 30, 60}
        r200_lr_auto_exposure_enabled = 16, // {0, 1}
        r200_lr_gain = 17, // 100 - 1600 (Units of 0.01)
        r200_lr_exposure = 18, // > 0 (Units of 0.1 ms)
        r200_emitter_enabled = 19, // {0, 1}
        r200_depth_control_preset = 20, // {0, 5}, 0 is default, 1-5 is low to high outlier rejection
        r200_depth_units = 21, // micrometers per increment in integer depth values, 1000 is default (mm scale)
        r200_depth_clamp_min = 22, // 0 - USHORT_MAX
        r200_depth_clamp_max = 23, // 0 - USHORT_MAX
        r200_disparity_mode_enabled = 24, // {0, 1}
        r200_disparity_multiplier = 25,
        r200_disparity_shift = 26
    };

    struct float2 { float x,y; };
    struct float3 { float x,y,z; };

    struct intrinsics : rs_intrinsics
    {
        float       hfov() const                                                        { return (atan2f(ppx + 0.5f, fx) + atan2f(width - (ppx + 0.5f), fx)) * 57.2957795f; }
        float       vfov() const                                                        { return (atan2f(ppy + 0.5f, fy) + atan2f(height - (ppy + 0.5f), fy)) * 57.2957795f; }
        distortion  model() const                                                       { return (distortion)rs_intrinsics::model; }

                    // Helpers for mapping between pixel coordinates and texture coordinates
        float2      pixel_to_texcoord(const float2 & pixel) const                       { return {(pixel.x+0.5f)/width, (pixel.y+0.5f)/height}; }
        float2      texcoord_to_pixel(const float2 & coord) const                       { return {coord.x*width - 0.5f, coord.y*height - 0.5f}; }

                    // Helpers for mapping from image coordinates into 3D space
        float3      deproject(const float2 & pixel, float depth) const                  { float3 point; rs_deproject_pixel_to_point(&point.x, this, &pixel.x, depth); return point; }
        float3      deproject_from_texcoord(const float2 & coord, float depth) const    { return deproject(texcoord_to_pixel(coord), depth); }

                    // Helpers for mapping from 3D space into image coordinates
        float2      project(const float3 & point) const                                 { float2 pixel; rs_project_point_to_pixel(&pixel.x, this, &point.x); return pixel; }
        float2      project_to_texcoord(const float3 & point) const                     { return pixel_to_texcoord(project(point)); }

        bool        operator == (const intrinsics & r) const                            { return memcmp(this, &r, sizeof(r)) == 0; }

    };
    struct extrinsics : rs_extrinsics
    {
        bool        is_identity() const                                                 { return rotation[0] == 1 && rotation[4] == 1 && translation[0] == 0 && translation[1] == 0 && translation[2] == 0; }
        float3      transform(const float3 & point) const                               { float3 p; rs_transform_point_to_point(&p.x, this, &point.x); return p; }

    };
    class context;
    class device;

    class error : public std::runtime_error
    {
        std::string function, args;
    public:
        error(rs_error * err) : std::runtime_error(rs_get_error_message(err)), function(rs_get_failed_function(err)), args(rs_get_failed_args(err)) { rs_free_error(err); }
        const std::string & get_failed_function() const { return function; }
        const std::string & get_failed_args() const { return args; }
        static void handle(rs_error * e) { if(e) throw error(e); }
    };

    class context
    {
        rs_context * handle;
        context(const context &) = delete;
        context & operator = (const context &) = delete;
    public:
        context()
        {
            rs_error * e = nullptr;
            handle = rs_create_context(3, &e);
            error::handle(e);
        }

        ~context()
        {
            rs_delete_context(handle, nullptr);
        }

        int get_device_count() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_count(handle, &e);
            error::handle(e);
            return r;
        }

        device * get_device(int index)
        {
            rs_error * e = nullptr;
            auto r = rs_get_device(handle, index, &e);
            error::handle(e);
            return (device *)r;
        }
    };

    class device
    {
        device() = delete;
        device(const device &) = delete;
        device & operator = (const device &) = delete;
        ~device() = delete;
    public:
        const char * get_name() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_name((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        const char * get_serial() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_serial((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        const char * get_firmware_version() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_firmware_version((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        extrinsics get_extrinsics(stream from_stream, stream to_stream) const
        {
            rs_error * e = nullptr;
            extrinsics extrin;
            rs_get_device_extrinsics((const rs_device *)this, (rs_stream)from_stream, (rs_stream)to_stream, &extrin, &e);
            error::handle(e);
            return extrin;
        }

        float get_depth_scale() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_depth_scale((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        bool supports_option(option option) const
        {
            rs_error * e = nullptr;
            auto r = rs_device_supports_option((const rs_device *)this, (rs_option)option, &e);
            error::handle(e);
            return r != 0;
        }

        int get_stream_mode_count(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_mode_count((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        void get_stream_mode(stream stream, int index, int & width, int & height, format & format, int & framerate) const
        {
            rs_error * e = nullptr;
            rs_get_stream_mode((const rs_device *)this, (rs_stream)stream, index, &width, &height, (rs_format *)&format, &framerate, &e);
            error::handle(e);
        }

        void enable_stream(stream stream, int width, int height, format format, int framerate)
        {
            rs_error * e = nullptr;
            rs_enable_stream((rs_device *)this, (rs_stream)stream, width, height, (rs_format)format, framerate, &e);
            error::handle(e);
        }

        void enable_stream(stream stream, preset preset)
        {
            rs_error * e = nullptr;
            rs_enable_stream_preset((rs_device *)this, (rs_stream)stream, (rs_preset)preset, &e);
            error::handle(e);
        }

        void disable_stream(stream stream)
        {
            rs_error * e = nullptr;
            rs_disable_stream((rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
        }

        bool is_stream_enabled(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_is_stream_enabled((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r != 0;
        }

        intrinsics get_stream_intrinsics(stream stream) const
        {
            rs_error * e = nullptr;
            intrinsics intrin;
            rs_get_stream_intrinsics((const rs_device *)this, (rs_stream)stream, &intrin, &e);
            error::handle(e);
            return intrin;
        }

        format get_stream_format(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_format((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return (format)r;
        }

        int get_stream_framerate(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_framerate((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        void start()
        {
            rs_error * e = nullptr;
            rs_start_device((rs_device *)this, &e);
            error::handle(e);
        }

        void stop()
        {
            rs_error * e = nullptr;
            rs_stop_device((rs_device *)this, &e);
            error::handle(e);
        }

        bool is_streaming() const
        {
            rs_error * e = nullptr;
            auto r = rs_is_device_streaming((const rs_device *)this, &e);
            error::handle(e);
            return r != 0;
        }

        void set_option(option option, int value)
        {
            rs_error * e = nullptr;
            rs_set_device_option((rs_device *)this, (rs_option)option, value, &e);
            error::handle(e);
        }

        int get_option(option option) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_option((const rs_device *)this, (rs_option)option, &e);
            error::handle(e);
            return r;
        }

        void wait_for_frames()
        {
            rs_error * e = nullptr;
            rs_wait_for_frames((rs_device *)this, &e);
            error::handle(e);
        }

        int get_frame_timestamp(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_frame_timestamp((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        const void * get_frame_data(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_frame_data((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }
    };

    std::ostream & operator << (std::ostream & o, stream stream) { return o << rs_stream_to_string((rs_stream)stream); }
    std::ostream & operator << (std::ostream & o, format format) { return o << rs_format_to_string((rs_format)format); }
    std::ostream & operator << (std::ostream & o, preset preset) { return o << rs_preset_to_string((rs_preset)preset); }
    std::ostream & operator << (std::ostream & o, distortion distortion) { return o << rs_distortion_to_string((rs_distortion)distortion); }
    std::ostream & operator << (std::ostream & o, option option) { return o << rs_option_to_string((rs_option)option); }
}
#endif
<commit_msg>added math header for osx<commit_after>#ifndef LIBREALSENSE_RS_HPP
#define LIBREALSENSE_RS_HPP

#include "rsutil.h"
#include <cstdint>
#include <sstream>
#include <math.h>

namespace rs
{

    enum class stream : int32_t
    {
        depth = 0, // Native stream of depth data produced by RealSense device
        color = 1, // Native stream of color data captured by RealSense device
        infrared = 2, // Native stream of infrared data captured by RealSense device
        infrared2 = 3, // Native stream of infrared data captured from a second viewpoint by RealSense device
        rectified_color = 4, // Synthetic stream containing undistorted color data with no extrinsic rotation from the depth stream
        color_aligned_to_depth = 5, // Synthetic stream containing color data but sharing intrinsics of depth stream
        depth_aligned_to_color = 6, // Synthetic stream containing depth data but sharing intrinsics of color stream
        depth_aligned_to_rectified_color = 7 // Synthetic stream containing depth data but sharing intrinsics of rectified color stream
    };

    enum class format : int32_t
    {
        any = 0,
        z16 = 1,
        yuyv = 2,
        rgb8 = 3,
        bgr8 = 4,
        rgba8 = 5,
        bgra8 = 6,
        y8 = 7,
        y16 = 8,
        raw10 = 9 // Four 10-bit luminance values encoded into a 5-byte macropixel
    };

    enum class preset : int32_t
    {
        best_quality = 0,
        largest_image = 1,
        highest_framerate = 2
    };

    enum class distortion : int32_t
    {
        none = 0, // Rectilinear images, no distortion compensation required
        modified_brown_conrady = 1, // Equivalent to Brown-Conrady distortion, except that tangential distortion is applied to radially distorted points
        inverse_brown_conrady = 2 // Equivalent to Brown-Conrady distortion, except undistorts image instead of distorting it
    };

    enum class option : int32_t
    {
        color_backlight_compensation = 0,
        color_brightness = 1,
        color_contrast = 2,
        color_exposure = 3,
        color_gain = 4,
        color_gamma = 5,
        color_hue = 6,
        color_saturation = 7,
        color_sharpness = 8,
        color_white_balance = 9,
        f200_laser_power = 10, // 0 - 15
        f200_accuracy = 11, // 0 - 3
        f200_motion_range = 12, // 0 - 100
        f200_filter_option = 13, // 0 - 7
        f200_confidence_threshold = 14, // 0 - 15
        f200_dynamic_fps = 15, // {2, 5, 15, 30, 60}
        r200_lr_auto_exposure_enabled = 16, // {0, 1}
        r200_lr_gain = 17, // 100 - 1600 (Units of 0.01)
        r200_lr_exposure = 18, // > 0 (Units of 0.1 ms)
        r200_emitter_enabled = 19, // {0, 1}
        r200_depth_control_preset = 20, // {0, 5}, 0 is default, 1-5 is low to high outlier rejection
        r200_depth_units = 21, // micrometers per increment in integer depth values, 1000 is default (mm scale)
        r200_depth_clamp_min = 22, // 0 - USHORT_MAX
        r200_depth_clamp_max = 23, // 0 - USHORT_MAX
        r200_disparity_mode_enabled = 24, // {0, 1}
        r200_disparity_multiplier = 25,
        r200_disparity_shift = 26
    };

    struct float2 { float x,y; };
    struct float3 { float x,y,z; };

    struct intrinsics : rs_intrinsics
    {
        float       hfov() const                                                        { return (atan2f(ppx + 0.5f, fx) + atan2f(width - (ppx + 0.5f), fx)) * 57.2957795f; }
        float       vfov() const                                                        { return (atan2f(ppy + 0.5f, fy) + atan2f(height - (ppy + 0.5f), fy)) * 57.2957795f; }
        distortion  model() const                                                       { return (distortion)rs_intrinsics::model; }

                    // Helpers for mapping between pixel coordinates and texture coordinates
        float2      pixel_to_texcoord(const float2 & pixel) const                       { return {(pixel.x+0.5f)/width, (pixel.y+0.5f)/height}; }
        float2      texcoord_to_pixel(const float2 & coord) const                       { return {coord.x*width - 0.5f, coord.y*height - 0.5f}; }

                    // Helpers for mapping from image coordinates into 3D space
        float3      deproject(const float2 & pixel, float depth) const                  { float3 point; rs_deproject_pixel_to_point(&point.x, this, &pixel.x, depth); return point; }
        float3      deproject_from_texcoord(const float2 & coord, float depth) const    { return deproject(texcoord_to_pixel(coord), depth); }

                    // Helpers for mapping from 3D space into image coordinates
        float2      project(const float3 & point) const                                 { float2 pixel; rs_project_point_to_pixel(&pixel.x, this, &point.x); return pixel; }
        float2      project_to_texcoord(const float3 & point) const                     { return pixel_to_texcoord(project(point)); }

        bool        operator == (const intrinsics & r) const                            { return memcmp(this, &r, sizeof(r)) == 0; }

    };
    struct extrinsics : rs_extrinsics
    {
        bool        is_identity() const                                                 { return rotation[0] == 1 && rotation[4] == 1 && translation[0] == 0 && translation[1] == 0 && translation[2] == 0; }
        float3      transform(const float3 & point) const                               { float3 p; rs_transform_point_to_point(&p.x, this, &point.x); return p; }

    };
    class context;
    class device;

    class error : public std::runtime_error
    {
        std::string function, args;
    public:
        error(rs_error * err) : std::runtime_error(rs_get_error_message(err)), function(rs_get_failed_function(err)), args(rs_get_failed_args(err)) { rs_free_error(err); }
        const std::string & get_failed_function() const { return function; }
        const std::string & get_failed_args() const { return args; }
        static void handle(rs_error * e) { if(e) throw error(e); }
    };

    class context
    {
        rs_context * handle;
        context(const context &) = delete;
        context & operator = (const context &) = delete;
    public:
        context()
        {
            rs_error * e = nullptr;
            handle = rs_create_context(3, &e);
            error::handle(e);
        }

        ~context()
        {
            rs_delete_context(handle, nullptr);
        }

        int get_device_count() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_count(handle, &e);
            error::handle(e);
            return r;
        }

        device * get_device(int index)
        {
            rs_error * e = nullptr;
            auto r = rs_get_device(handle, index, &e);
            error::handle(e);
            return (device *)r;
        }
    };

    class device
    {
        device() = delete;
        device(const device &) = delete;
        device & operator = (const device &) = delete;
        ~device() = delete;
    public:
        const char * get_name() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_name((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        const char * get_serial() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_serial((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        const char * get_firmware_version() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_firmware_version((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        extrinsics get_extrinsics(stream from_stream, stream to_stream) const
        {
            rs_error * e = nullptr;
            extrinsics extrin;
            rs_get_device_extrinsics((const rs_device *)this, (rs_stream)from_stream, (rs_stream)to_stream, &extrin, &e);
            error::handle(e);
            return extrin;
        }

        float get_depth_scale() const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_depth_scale((const rs_device *)this, &e);
            error::handle(e);
            return r;
        }

        bool supports_option(option option) const
        {
            rs_error * e = nullptr;
            auto r = rs_device_supports_option((const rs_device *)this, (rs_option)option, &e);
            error::handle(e);
            return r != 0;
        }

        int get_stream_mode_count(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_mode_count((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        void get_stream_mode(stream stream, int index, int & width, int & height, format & format, int & framerate) const
        {
            rs_error * e = nullptr;
            rs_get_stream_mode((const rs_device *)this, (rs_stream)stream, index, &width, &height, (rs_format *)&format, &framerate, &e);
            error::handle(e);
        }

        void enable_stream(stream stream, int width, int height, format format, int framerate)
        {
            rs_error * e = nullptr;
            rs_enable_stream((rs_device *)this, (rs_stream)stream, width, height, (rs_format)format, framerate, &e);
            error::handle(e);
        }

        void enable_stream(stream stream, preset preset)
        {
            rs_error * e = nullptr;
            rs_enable_stream_preset((rs_device *)this, (rs_stream)stream, (rs_preset)preset, &e);
            error::handle(e);
        }

        void disable_stream(stream stream)
        {
            rs_error * e = nullptr;
            rs_disable_stream((rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
        }

        bool is_stream_enabled(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_is_stream_enabled((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r != 0;
        }

        intrinsics get_stream_intrinsics(stream stream) const
        {
            rs_error * e = nullptr;
            intrinsics intrin;
            rs_get_stream_intrinsics((const rs_device *)this, (rs_stream)stream, &intrin, &e);
            error::handle(e);
            return intrin;
        }

        format get_stream_format(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_format((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return (format)r;
        }

        int get_stream_framerate(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_stream_framerate((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        void start()
        {
            rs_error * e = nullptr;
            rs_start_device((rs_device *)this, &e);
            error::handle(e);
        }

        void stop()
        {
            rs_error * e = nullptr;
            rs_stop_device((rs_device *)this, &e);
            error::handle(e);
        }

        bool is_streaming() const
        {
            rs_error * e = nullptr;
            auto r = rs_is_device_streaming((const rs_device *)this, &e);
            error::handle(e);
            return r != 0;
        }

        void set_option(option option, int value)
        {
            rs_error * e = nullptr;
            rs_set_device_option((rs_device *)this, (rs_option)option, value, &e);
            error::handle(e);
        }

        int get_option(option option) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_device_option((const rs_device *)this, (rs_option)option, &e);
            error::handle(e);
            return r;
        }

        void wait_for_frames()
        {
            rs_error * e = nullptr;
            rs_wait_for_frames((rs_device *)this, &e);
            error::handle(e);
        }

        int get_frame_timestamp(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_frame_timestamp((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }

        const void * get_frame_data(stream stream) const
        {
            rs_error * e = nullptr;
            auto r = rs_get_frame_data((const rs_device *)this, (rs_stream)stream, &e);
            error::handle(e);
            return r;
        }
    };

    std::ostream & operator << (std::ostream & o, stream stream) { return o << rs_stream_to_string((rs_stream)stream); }
    std::ostream & operator << (std::ostream & o, format format) { return o << rs_format_to_string((rs_format)format); }
    std::ostream & operator << (std::ostream & o, preset preset) { return o << rs_preset_to_string((rs_preset)preset); }
    std::ostream & operator << (std::ostream & o, distortion distortion) { return o << rs_distortion_to_string((rs_distortion)distortion); }
    std::ostream & operator << (std::ostream & o, option option) { return o << rs_option_to_string((rs_option)option); }
}
#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_FILE_HPP_INCLUDED
#define TORRENT_FILE_HPP_INCLUDED

#include <memory>

#include <boost/noncopyable.hpp>
#include <boost/filesystem/path.hpp>

namespace libtorrent
{

	struct file_error: std::runtime_error
	{
		file_error(std::string const& msg): std::runtime_error(msg) {}
	};

	class file: public boost::noncopyable
	{
	public:

#ifdef _MSC_VER
		typedef _int64 size_type;
#else
		typedef long long int size_type;
#endif

		class open_mode
		{
		friend file;
		public:

			open_mode operator|(open_mode m)
			{ return open_mode(m.m_mask | m_mask); }

		private:

			open_mode(int val): m_mask(val) {}
			int m_mask;
		};

		static open_mode in;
		static open_mode out;

		file();
		file(boost::filesystem::path const& p, open_mode m);
		~file();

		void open(boost::filesystem::path const& p, open_mode m);
		void close();

		size_type write(const char*, size_type num_bytes);
		size_type read(char*, size_type num_bytes);

		void seek(size_type pos);
		size_type tell();

	private:

		struct impl;
		const std::auto_ptr<impl> m_impl;

	};

}

#endif // TORRENT_FILE_HPP_INCLUDED

<commit_msg>*** empty log message ***<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_FILE_HPP_INCLUDED
#define TORRENT_FILE_HPP_INCLUDED

#include <memory>

#include <boost/noncopyable.hpp>
#include <boost/filesystem/path.hpp>

namespace libtorrent
{

	struct file_error: std::runtime_error
	{
		file_error(std::string const& msg): std::runtime_error(msg) {}
	};

	class file: public boost::noncopyable
	{
	public:

#ifdef _MSC_VER
		typedef _int64 size_type;
#else
		typedef long long int size_type;
#endif

		class seek_mode
		{
		friend file;
		seek_mode(int v): m_val(v) {}
		int m_val;
		};

		static seek_mode begin;
		static seek_mode end;

		class open_mode
		{
		friend file;
		public:

			open_mode(): m_mask(0) {}

			open_mode operator|(open_mode m) const
			{ return open_mode(m.m_mask | m_mask); }

			open_mode operator|=(open_mode m)
			{
				m_mask |= m.m_mask;
				return *this;
			}

		private:

			open_mode(int val): m_mask(val) {}
			int m_mask;
		};

		static open_mode in;
		static open_mode out;

		file();
		file(boost::filesystem::path const& p, open_mode m);
		~file();

		void open(boost::filesystem::path const& p, open_mode m);
		void close();

		size_type write(const char*, size_type num_bytes);
		size_type read(char*, size_type num_bytes);

		void seek(size_type pos, seek_mode m);
		size_type tell();

	private:

		struct impl;
		const std::auto_ptr<impl> m_impl;

	};

}

#endif // TORRENT_FILE_HPP_INCLUDED

<|endoftext|>


<commit_before>#ifndef _HDB_TRIE_H_
#define _HDB_TRIE_H_

#include <iostream>

#include <am/concept/DataType.h>
#include <hdb/HugeDB.h>
#include <sdb/SequentialDB.h>
#include "traits.h"

NS_IZENELIB_AM_BEGIN

/**
 * Maintain all edges' information in a Trie data structure with the form of
 * database table.
 * As all kinds of graph in computer science, Trie's graph representation also
 * contains two types of basic elements, node and edge.
 * Be different from other graphs, Each edge in Trie has a character propery.
 * So Given a node, the edges from the root node to the given node form a path,
 * and all the characters on the path form a string. That is to say, each node in
 * Trie can represent a string.
 * Node may contains pointers to numerous child nodes, A parent node P has pointer
 * to a child node C means, the string represented by P is the prefix of the string
 * represented by C. For example, node "ca" is the parent of node "cat".
 * Node can be an leaf node means, the string it represents is a user input string.
 * What is more, a node is a leaf node DOES NOT indicate it does not have children.
 * For example, user insert "cat" into trie, so node "cat" is a leaf node, however,
 * if user insert "catch" too, then leaf node "cat" could become the parent of
 * node "catc".
 */
template <typename CharType,
          typename NodeIDType = uint64_t,
          typename LockType = izenelib::util::NullLock>
class PartitionTrie
{
    // hdb is fast for large number of random insertions
    typedef std::pair<NodeIDType, CharType> EdgeTableKeyType;
    typedef NodeIDType EdgeTableValueType;
    typedef DataType<EdgeTableKeyType, EdgeTableValueType> EdgeTableRecordType;
    typedef izenelib::hdb::ordered_hdb_fixed<EdgeTableKeyType, EdgeTableValueType , LockType> EdgeTableType;

    // sdb is fast for sequential insertions
    typedef NodeIDType DataTableKeyType;
    typedef bool DataTableValueType;
    typedef DataType<DataTableKeyType, DataTableValueType> DataTableRecordType;
    typedef izenelib::sdb::ordered_sdb_fixed<DataTableKeyType, DataTableValueType , LockType> DataTableType;

    typedef PartitionTrie<CharType, NodeIDType, LockType> ThisType;

public:

    PartitionTrie(const std::string& dbname)
    :   closed_(true), dbname_(dbname),
        edgeTable_(dbname_ + ".hdbtrie.edgetable"),
        dataTable_(dbname_ + ".hdbtrie.datatable.sdb")
    {
        nextNID_ = NodeIDTraits<NodeIDType>::MaxValue;
    }

    virtual ~PartitionTrie()
    {
        flush();
    }

    /**
     * @brief Open all db files, maps them to memory. Call it
     *        after config() and before any insert() or find() operations.
     */
    void open()
    {
        dataTable_.setDegree(32);
        dataTable_.setPageSize(1024);
        dataTable_.setCacheSize(64*1024);
        dataTable_.open();

        edgeTable_.setDegree(128);
        edgeTable_.setPageSize(8192);
        edgeTable_.setCachedRecordsNumber(2500000);
        edgeTable_.setMergeFactor(2);
        edgeTable_.open();
        nextNID_ = edgeTable_.numItems() + NodeIDTraits<NodeIDType>::MinValue;
    }

    void flush()
    {
        edgeTable_.flush();
        dataTable_.flush();
    }

    /**
     * @brief Write back informations back to db.
     */
    void close()
    {
        edgeTable_.close();
        dataTable_.close();
    }

    /**
     * @brief Optimize read performance, e.g. get() and findPrefix()
     */
    void optimize()
    {
        edgeTable_.optimize();
    }

    /**
     * @brief Insert key value pairs into Trie.
     */
    void insert(const std::vector<CharType>& key)
    {
        if( key.size() == 0) return;

        NodeIDType nid = NodeIDTraits<NodeIDType>::RootValue;
        for( size_t i=0; i< key.size(); i++ )
        {
            NodeIDType tmp = NodeIDType();
            addEdge(key[i], nid, tmp);
            nid = tmp;
        }
        setLeaf(nid);
    }

    /**
     * @brief Get value for a given key.
     * @return false if key doesn't exist
     *         true otherwise
     */
    bool get(const std::vector<CharType>& key)
    {
        if(key.size() == 0) return false;

        NodeIDType nid = NodeIDTraits<NodeIDType>::RootValue;
        for( size_t i=0; i<key.size(); i++ )
        {
            NodeIDType tmp = NodeIDType();
            if( !getEdge(key[i], nid, tmp) )
                return false;
            nid = tmp;
        }
        return isLeaf(nid);
    }

    /**
     * @brief Get a list of values whose keys match the wildcard query. Only "*" and
     * "?" are supported currently, legal input looks like "ea?th", "her*", or "*ear?h".
     * @return true at leaset one result found.
     *         false nothing found.
     */
    bool findRegExp(const std::vector<CharType>& regexp,
        std::vector<std::vector<CharType> >& keyList,
        int maximumResultNumber)
    {
        keyList.clear();
        std::vector<CharType> prefix;
        findRegExp_(regexp, 0, NodeIDTraits<NodeIDType>::RootValue,
            prefix, keyList, maximumResultNumber);
        return keyList.size() ? true : false;
    }

    void concatenate(ThisType& other, NodeIDType start) {
        NodeIDType base = nextNID_;

        EdgeTableRecordType edge;
        typename EdgeTableType::HDBCursor ecur = other.edgeTable_.get_first_Locn();
        while(other.edgeTable_.get(ecur,edge)) {
            //std::cout << edge.key.first << "," << edge.key.second << "," << edge.value << "\t==>\t";
            if(edge.key.first >= start ) edge.key.first += base;
            if(edge.value >= start ) edge.value += base;
            //std::cout << edge.key.first << "," << edge.key.second << "," << edge.value << std::endl;
            edgeTable_.insertValue(edge.key, edge.value);
            other.edgeTable_.seq(ecur);
        }

        DataTableRecordType data;
        typename DataTableType::SDBCursor dcur = other.dataTable_.get_first_Locn();
        while(other.dataTable_.get(dcur,data)) {
            if(data.key >= start) data.key += base;
            dataTable_.insertValue(data.key, data.value);
            other.dataTable_.seq(dcur);
        }

        nextNID_ = base + other.nextNID_;
    }

    NodeIDType nextNodeID() {
        return nextNID_;
    }

    /**
     * @return number of key value pairs inserted.
     */
    unsigned int num_items()
    {
        return dataTable_.numItems();
    }

    /**
     * @brief Display debug information.
     */
    void display()
    {
        edgeTable_.display();
        dataTable_.display();
    }

protected:

    /**
     * Given the NID of parent node and the edge's character property,
     * generate the child node's NID.
     * @param   ch          edge's character property
     *          parentNID   NID of parent node
     *          childNID    NID of child node
     * @return  true    if child node is generated successfully
     *          false   if key exists already
     */
    bool addEdge(const CharType ch, const NodeIDType parentNID, NodeIDType& childNID)
    {
        EdgeTableKeyType etKey(parentNID, ch);

        // if NID is found, just return
        if(edgeTable_.getValue(etKey, childNID))
            return false;

        childNID = nextNID_;
        ++nextNID_;
        if(nextNID_ > NodeIDTraits<NodeIDType>::MaxValue)
            throw std::runtime_error("NID allocation out of range");

        edgeTable_.insertValue(etKey, childNID);
        return true;
    }

    /**
     * Given the NID of parent node and the edge's character property,
     * find the child node's NID.
     * @param   ch          edge's character property
     *          parentNID   NID of parent node
     *          childNID    NID of child node
     * @return  true    if successfully
     *          false   if child does not exist yet
     */
    bool getEdge(const CharType& ch, const NodeIDType& parentNID, NodeIDType& childNID)
    {
        EdgeTableKeyType etKey(parentNID, ch);
        NodeIDType value = NodeIDType();

        // Return false if edge doesn't exist
        if(!edgeTable_.getValue(etKey, value))
            return false;

        childNID = value;
        return true;
    }

    /**
     * Store key's nid and userdata into SDB.
     * @return true     successfully
     *         false    key exists already
     */
    void setLeaf( const NodeIDType nid)
    {
        dataTable_.insertValue(nid,true);
    }

    /**
     * Retrieve userdata stored in SDB by given key.
     * @return true     successfully
     *         false    given key does not exist
     */
    bool isLeaf( const NodeIDType nid)
    {
        bool flag = false;
        return dataTable_.getValue(nid, flag);
    }

    void findRegExp_(const std::vector<CharType>& regexp,
        const size_t& startPos, const NodeIDType& nid,
        std::vector<CharType>& prefix,
        std::vector<std::vector<CharType> >& keyList,
        int maximumResultNumber)
    {
        if(keyList.size() >= (size_t)maximumResultNumber)
            return;

        if(startPos == regexp.size())
        {
            if(isLeaf(nid))
                keyList.push_back(prefix);
            return;
        }

        // std::cout << regexp[startPos] << "," << nid << std::endl;

        switch( regexp[startPos] )
        {
            case 42:    //"*"
            {
                EdgeTableKeyType minKey(nid, NumericTraits<CharType>::MinValue);
                EdgeTableKeyType maxKey(nid, NumericTraits<CharType>::MaxValue);

                std::vector<EdgeTableRecordType> result;
                edgeTable_.getValueBetween(result, minKey, maxKey);

                for(size_t i = 0; i <result.size(); i++ ) {
                    prefix.push_back(result[i].key.second);
                    findRegExp_(regexp, startPos, result[i].value, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }

                findRegExp_(regexp, startPos+1, nid, prefix,
                    keyList, maximumResultNumber);
                break;
            }
            case 63:    //"?"
            {
                EdgeTableKeyType minKey(nid, NumericTraits<CharType>::MinValue);
                EdgeTableKeyType maxKey(nid, NumericTraits<CharType>::MaxValue);

                std::vector<EdgeTableRecordType> result;
                edgeTable_.getValueBetween(result, minKey, maxKey);

                for(size_t i = 0; i <result.size(); i++ ) {
                    prefix.push_back(result[i].key.second);
                    findRegExp_(regexp, startPos+1, result[i].value, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }
                break;
            }
            default:
            {
                EdgeTableKeyType key(nid, regexp[startPos]);
                NodeIDType nxtNode = NodeIDType();
                if( edgeTable_.getValue(key, nxtNode) ) {
                    prefix.push_back(regexp[startPos]);
                    findRegExp_(regexp, startPos+1, nxtNode, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }
                break;
            }
        }
    }

private:

    bool closed_;

    std::string dbname_;

    EdgeTableType edgeTable_;

    DataTableType dataTable_;

    NodeIDType nextNID_;

};

/**
 * @see SDBTrie
 */
template <typename StringType,
          typename NodeIDType = uint64_t,
          typename LockType = izenelib::util::NullLock>
class PartitionTrie2
{
    typedef typename StringType::value_type CharType;
    typedef PartitionTrie2<StringType, NodeIDType, LockType> ThisType;
    typedef PartitionTrie<CharType, NodeIDType, LockType> PartitionTrieType;

public:

    PartitionTrie2(const std::string name)
    :   trie_(name) {}

    virtual ~PartitionTrie2(){}

    void openForRead(){ trie_.openForRead(); }
    void openForWrite(){ trie_.openForWrite(); }
    void open(){ trie_.open(); }
    void flush(){ trie_.flush(); }
    void close(){ trie_.close(); }
    void optimize(){ trie_.optimize(); }

    void insert(const StringType& key)
    {
        CharType* chArray = (CharType*)key.c_str();
        size_t chCount = key.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);
        trie_.insert(chVector);
    }

    bool get(const StringType& key)
    {
        CharType* chArray = (CharType*)key.c_str();
        size_t chCount = key.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);
        return trie_.get(chVector);
    }

    bool findRegExp(const StringType& regexp,
        std::vector<StringType>& keyList,
        int maximumResultNumber)
    {
        CharType* chArray = (CharType*)regexp.c_str();
        size_t chCount = regexp.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);

        std::vector< std::vector<CharType> > resultList;
        if( false == trie_.findRegExp(chVector, resultList, maximumResultNumber) )
            return false;

        for(size_t i = 0; i< resultList.size(); i++ )
        {
            StringType tmp(resultList[i].begin(), resultList[i].end() );
            keyList.push_back(tmp);
        }
        return true;
    }

    void concatenate(ThisType& other, NodeIDType start) {
        trie_.concatenate(other.trie_, start);
    }

    NodeIDType nextNodeID() {
        return trie_.nextNodeID();
    }

    unsigned int num_items() { return trie_.num_items(); }

    void display() { trie_.display(); }

private:
    PartitionTrieType trie_;
};

NS_IZENELIB_AM_END

#endif
<commit_msg>fix compile error<commit_after>#ifndef _PARTITION_TRIE_H_
#define _PARTITION_TRIE_H_

#include <iostream>

#include <am/concept/DataType.h>
#include <hdb/HugeDB.h>
#include <sdb/SequentialDB.h>
#include "traits.h"

NS_IZENELIB_AM_BEGIN

/**
 * Maintain all edges' information in a Trie data structure with the form of
 * database table.
 * As all kinds of graph in computer science, Trie's graph representation also
 * contains two types of basic elements, node and edge.
 * Be different from other graphs, Each edge in Trie has a character propery.
 * So Given a node, the edges from the root node to the given node form a path,
 * and all the characters on the path form a string. That is to say, each node in
 * Trie can represent a string.
 * Node may contains pointers to numerous child nodes, A parent node P has pointer
 * to a child node C means, the string represented by P is the prefix of the string
 * represented by C. For example, node "ca" is the parent of node "cat".
 * Node can be an leaf node means, the string it represents is a user input string.
 * What is more, a node is a leaf node DOES NOT indicate it does not have children.
 * For example, user insert "cat" into trie, so node "cat" is a leaf node, however,
 * if user insert "catch" too, then leaf node "cat" could become the parent of
 * node "catc".
 */
template <typename CharType,
          typename NodeIDType = uint64_t,
          typename LockType = izenelib::util::NullLock>
class PartitionTrie
{
    // hdb is fast for large number of random insertions
    typedef std::pair<NodeIDType, CharType> EdgeTableKeyType;
    typedef NodeIDType EdgeTableValueType;
    typedef DataType<EdgeTableKeyType, EdgeTableValueType> EdgeTableRecordType;
    typedef izenelib::hdb::ordered_hdb_fixed<EdgeTableKeyType, EdgeTableValueType , LockType> EdgeTableType;

    // sdb is fast for sequential insertions
    typedef NodeIDType DataTableKeyType;
    typedef bool DataTableValueType;
    typedef DataType<DataTableKeyType, DataTableValueType> DataTableRecordType;
    typedef izenelib::sdb::ordered_sdb_fixed<DataTableKeyType, DataTableValueType , LockType> DataTableType;

    typedef PartitionTrie<CharType, NodeIDType, LockType> ThisType;

public:

    PartitionTrie(const std::string& dbname)
    :   closed_(true), dbname_(dbname),
        edgeTable_(dbname_ + ".hdbtrie.edgetable"),
        dataTable_(dbname_ + ".hdbtrie.datatable.sdb")
    {
        nextNID_ = NodeIDTraits<NodeIDType>::MaxValue;
    }

    virtual ~PartitionTrie()
    {
        flush();
    }

    /**
     * @brief Open all db files, maps them to memory. Call it
     *        after config() and before any insert() or find() operations.
     */
    void open()
    {
        dataTable_.setDegree(32);
        dataTable_.setPageSize(1024);
        dataTable_.setCacheSize(64*1024);
        dataTable_.open();

        edgeTable_.setDegree(128);
        edgeTable_.setPageSize(8192);
        edgeTable_.setCachedRecordsNumber(2500000);
        edgeTable_.setMergeFactor(2);
        edgeTable_.open();
        nextNID_ = edgeTable_.numItems() + NodeIDTraits<NodeIDType>::MinValue;
    }

    void flush()
    {
        edgeTable_.flush();
        dataTable_.flush();
    }

    /**
     * @brief Write back informations back to db.
     */
    void close()
    {
        edgeTable_.close();
        dataTable_.close();
    }

    /**
     * @brief Optimize read performance, e.g. get() and findPrefix()
     */
    void optimize()
    {
        edgeTable_.optimize();
    }

    /**
     * @brief Insert key value pairs into Trie.
     */
    void insert(const std::vector<CharType>& key)
    {
        if( key.size() == 0) return;

        NodeIDType nid = NodeIDTraits<NodeIDType>::RootValue;
        for( size_t i=0; i< key.size(); i++ )
        {
            NodeIDType tmp = NodeIDType();
            addEdge(key[i], nid, tmp);
            nid = tmp;
        }
        setLeaf(nid);
    }

    /**
     * @brief Get value for a given key.
     * @return false if key doesn't exist
     *         true otherwise
     */
    bool get(const std::vector<CharType>& key)
    {
        if(key.size() == 0) return false;

        NodeIDType nid = NodeIDTraits<NodeIDType>::RootValue;
        for( size_t i=0; i<key.size(); i++ )
        {
            NodeIDType tmp = NodeIDType();
            if( !getEdge(key[i], nid, tmp) )
                return false;
            nid = tmp;
        }
        return isLeaf(nid);
    }

    /**
     * @brief Get a list of values whose keys match the wildcard query. Only "*" and
     * "?" are supported currently, legal input looks like "ea?th", "her*", or "*ear?h".
     * @return true at leaset one result found.
     *         false nothing found.
     */
    bool findRegExp(const std::vector<CharType>& regexp,
        std::vector<std::vector<CharType> >& keyList,
        int maximumResultNumber)
    {
        keyList.clear();
        std::vector<CharType> prefix;
        findRegExp_(regexp, 0, NodeIDTraits<NodeIDType>::RootValue,
            prefix, keyList, maximumResultNumber);
        return keyList.size() ? true : false;
    }

    void concatenate(ThisType& other, NodeIDType start) {
        NodeIDType base = nextNID_;

        EdgeTableRecordType edge;
        typename EdgeTableType::HDBCursor ecur = other.edgeTable_.get_first_Locn();
        while(other.edgeTable_.get(ecur,edge)) {
            //std::cout << edge.key.first << "," << edge.key.second << "," << edge.value << "\t==>\t";
            if(edge.key.first >= start ) edge.key.first += base;
            if(edge.value >= start ) edge.value += base;
            //std::cout << edge.key.first << "," << edge.key.second << "," << edge.value << std::endl;
            edgeTable_.insertValue(edge.key, edge.value);
            other.edgeTable_.seq(ecur);
        }

        DataTableRecordType data;
        typename DataTableType::SDBCursor dcur = other.dataTable_.get_first_Locn();
        while(other.dataTable_.get(dcur,data)) {
            if(data.key >= start) data.key += base;
            dataTable_.insertValue(data.key, data.value);
            other.dataTable_.seq(dcur);
        }

        nextNID_ = base + other.nextNID_;
    }

    NodeIDType nextNodeID() {
        return nextNID_;
    }

    /**
     * @return number of key value pairs inserted.
     */
    unsigned int num_items()
    {
        return dataTable_.numItems();
    }

    /**
     * @brief Display debug information.
     */
    void display()
    {
        edgeTable_.display();
        dataTable_.display();
    }

protected:

    /**
     * Given the NID of parent node and the edge's character property,
     * generate the child node's NID.
     * @param   ch          edge's character property
     *          parentNID   NID of parent node
     *          childNID    NID of child node
     * @return  true    if child node is generated successfully
     *          false   if key exists already
     */
    bool addEdge(const CharType ch, const NodeIDType parentNID, NodeIDType& childNID)
    {
        EdgeTableKeyType etKey(parentNID, ch);

        // if NID is found, just return
        if(edgeTable_.getValue(etKey, childNID))
            return false;

        childNID = nextNID_;
        ++nextNID_;
        if(nextNID_ > NodeIDTraits<NodeIDType>::MaxValue)
            throw std::runtime_error("NID allocation out of range");

        edgeTable_.insertValue(etKey, childNID);
        return true;
    }

    /**
     * Given the NID of parent node and the edge's character property,
     * find the child node's NID.
     * @param   ch          edge's character property
     *          parentNID   NID of parent node
     *          childNID    NID of child node
     * @return  true    if successfully
     *          false   if child does not exist yet
     */
    bool getEdge(const CharType& ch, const NodeIDType& parentNID, NodeIDType& childNID)
    {
        EdgeTableKeyType etKey(parentNID, ch);
        NodeIDType value = NodeIDType();

        // Return false if edge doesn't exist
        if(!edgeTable_.getValue(etKey, value))
            return false;

        childNID = value;
        return true;
    }

    /**
     * Store key's nid and userdata into SDB.
     * @return true     successfully
     *         false    key exists already
     */
    void setLeaf( const NodeIDType nid)
    {
        dataTable_.insertValue(nid,true);
    }

    /**
     * Retrieve userdata stored in SDB by given key.
     * @return true     successfully
     *         false    given key does not exist
     */
    bool isLeaf( const NodeIDType nid)
    {
        bool flag = false;
        return dataTable_.getValue(nid, flag);
    }

    void findRegExp_(const std::vector<CharType>& regexp,
        const size_t& startPos, const NodeIDType& nid,
        std::vector<CharType>& prefix,
        std::vector<std::vector<CharType> >& keyList,
        int maximumResultNumber)
    {
        if(keyList.size() >= (size_t)maximumResultNumber)
            return;

        if(startPos == regexp.size())
        {
            if(isLeaf(nid))
                keyList.push_back(prefix);
            return;
        }

        // std::cout << regexp[startPos] << "," << nid << std::endl;

        switch( regexp[startPos] )
        {
            case 42:    //"*"
            {
                EdgeTableKeyType minKey(nid, NumericTraits<CharType>::MinValue);
                EdgeTableKeyType maxKey(nid, NumericTraits<CharType>::MaxValue);

                std::vector<EdgeTableRecordType> result;
                edgeTable_.getValueBetween(result, minKey, maxKey);

                for(size_t i = 0; i <result.size(); i++ ) {
                    prefix.push_back(result[i].key.second);
                    findRegExp_(regexp, startPos, result[i].value, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }

                findRegExp_(regexp, startPos+1, nid, prefix,
                    keyList, maximumResultNumber);
                break;
            }
            case 63:    //"?"
            {
                EdgeTableKeyType minKey(nid, NumericTraits<CharType>::MinValue);
                EdgeTableKeyType maxKey(nid, NumericTraits<CharType>::MaxValue);

                std::vector<EdgeTableRecordType> result;
                edgeTable_.getValueBetween(result, minKey, maxKey);

                for(size_t i = 0; i <result.size(); i++ ) {
                    prefix.push_back(result[i].key.second);
                    findRegExp_(regexp, startPos+1, result[i].value, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }
                break;
            }
            default:
            {
                EdgeTableKeyType key(nid, regexp[startPos]);
                NodeIDType nxtNode = NodeIDType();
                if( edgeTable_.getValue(key, nxtNode) ) {
                    prefix.push_back(regexp[startPos]);
                    findRegExp_(regexp, startPos+1, nxtNode, prefix,
                        keyList, maximumResultNumber);
                    prefix.pop_back();
                }
                break;
            }
        }
    }

private:

    bool closed_;

    std::string dbname_;

    EdgeTableType edgeTable_;

    DataTableType dataTable_;

    NodeIDType nextNID_;

};

/**
 * @see SDBTrie
 */
template <typename StringType,
          typename NodeIDType = uint64_t,
          typename LockType = izenelib::util::NullLock>
class PartitionTrie2
{
    typedef typename StringType::value_type CharType;
    typedef PartitionTrie2<StringType, NodeIDType, LockType> ThisType;
    typedef PartitionTrie<CharType, NodeIDType, LockType> PartitionTrieType;

public:

    PartitionTrie2(const std::string name)
    :   trie_(name) {}

    virtual ~PartitionTrie2(){}

    void openForRead(){ trie_.openForRead(); }
    void openForWrite(){ trie_.openForWrite(); }
    void open(){ trie_.open(); }
    void flush(){ trie_.flush(); }
    void close(){ trie_.close(); }
    void optimize(){ trie_.optimize(); }

    void insert(const StringType& key)
    {
        CharType* chArray = (CharType*)key.c_str();
        size_t chCount = key.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);
        trie_.insert(chVector);
    }

    bool get(const StringType& key)
    {
        CharType* chArray = (CharType*)key.c_str();
        size_t chCount = key.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);
        return trie_.get(chVector);
    }

    bool findRegExp(const StringType& regexp,
        std::vector<StringType>& keyList,
        int maximumResultNumber)
    {
        CharType* chArray = (CharType*)regexp.c_str();
        size_t chCount = regexp.length();
        std::vector<CharType> chVector(chArray, chArray+chCount);

        std::vector< std::vector<CharType> > resultList;
        if( false == trie_.findRegExp(chVector, resultList, maximumResultNumber) )
            return false;

        for(size_t i = 0; i< resultList.size(); i++ )
        {
            StringType tmp(resultList[i].begin(), resultList[i].end() );
            keyList.push_back(tmp);
        }
        return true;
    }

    void concatenate(ThisType& other, NodeIDType start) {
        trie_.concatenate(other.trie_, start);
    }

    NodeIDType nextNodeID() {
        return trie_.nextNodeID();
    }

    unsigned int num_items() { return trie_.num_items(); }

    void display() { trie_.display(); }

private:
    PartitionTrieType trie_;
};

NS_IZENELIB_AM_END

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {
enum GeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T>
class geometry : private boost::noncopyable
{
public:
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
public:
    geometry () {}

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    virtual int type() const=0;
    virtual double area() const=0;
    virtual bool hit_test(value_type x,value_type y, double tol) const=0;
    virtual void label_position(double *x, double *y) const=0;
    virtual void move_to(value_type x,value_type y)=0;
    virtual void line_to(value_type x,value_type y)=0;
    virtual unsigned num_points() const = 0;
    virtual unsigned vertex(double* x, double* y) const=0;
    virtual void rewind(unsigned) const=0;
    virtual void set_capacity(size_t size)=0;
    virtual ~geometry() {}
};

template <typename T>
class point : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef typename geometry<T>::value_type value_type;
private:
    vertex_type pt_;
public:
    point() : geometry<T>() {}

    int type() const
    {
        return Point;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        *x = pt_.x;
        *y = pt_.y;
    }

    void move_to(value_type x,value_type y)
    {
        pt_.x = x;
        pt_.y = y;
    }

    void line_to(value_type ,value_type ) {}

    unsigned num_points() const
    {
        return 1;
    }

    unsigned vertex(double* x, double* y) const
    {
        *x = pt_.x;
        *y = pt_.y;
        return SEG_LINETO;
    }

    void rewind(unsigned ) const {}

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_in_circle(pt_.x,pt_.y, x,y,tol);
    }

    void set_capacity(size_t) {}
    virtual ~point() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class polygon //: public geometry<T>
{
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
    typedef Container<vertex_type> container_type;

private:
    container_type cont_;
    mutable unsigned itr_;
public:

    typedef typename container_type::const_iterator iterator;

    iterator begin() const
    {
	return cont_.begin();
    }

    iterator end() const
    {
	return cont_.end();
    }

    polygon()
        : //geometry_base(),
        itr_(0)
    {}

    int type() const
    {
        return Polygon;
    }

    double area() const
    {
        double sum = 0.0;
        double x(0);
        double y(0);
        rewind(0);
        double xs = x;
        double ys = y;
        for (unsigned i=0;i<num_points();++i)
        {
            double x0,y0;
            vertex(&x0,&y0);
            sum += x * y0 - y * x0;
            x = x0;
            y = y0;
        }
        return (sum + x * ys - y * xs) * 0.5;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }
    void label_position(double *x, double *y) const
    {
        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double) const
    {
        return point_inside_path(x,y,cont_.begin(),cont_.end());
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    //virtual ~polygon() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class line_string : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry_base::value_type value_type;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef Container<vertex_type> container_type;
private:
    container_type cont_;
    mutable unsigned itr_;
public:
    line_string()
        : geometry_base(),
          itr_(0)
    {}

    int type() const
    {
        return LineString;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        // calculate mid point on line string
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }
    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    virtual ~line_string() {}
};

//typedef point<vertex2d> point_impl;
//typedef line_string<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> point_impl;
typedef polygon<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> polygon_impl;

typedef polygon_impl geometry2d;
typedef boost::shared_ptr<geometry2d> geometry_ptr;
typedef boost::ptr_vector<geometry2d> geometry_containter;
}

#endif //GEOMETRY_HPP
<commit_msg>+ make typdefs public<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {
enum GeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T>
class geometry : private boost::noncopyable
{
public:
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
public:
    geometry () {}

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    virtual int type() const=0;
    virtual double area() const=0;
    virtual bool hit_test(value_type x,value_type y, double tol) const=0;
    virtual void label_position(double *x, double *y) const=0;
    virtual void move_to(value_type x,value_type y)=0;
    virtual void line_to(value_type x,value_type y)=0;
    virtual unsigned num_points() const = 0;
    virtual unsigned vertex(double* x, double* y) const=0;
    virtual void rewind(unsigned) const=0;
    virtual void set_capacity(size_t size)=0;
    virtual ~geometry() {}
};

template <typename T>
class point : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef typename geometry<T>::value_type value_type;
private:
    vertex_type pt_;
public:
    point() : geometry<T>() {}

    int type() const
    {
        return Point;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        *x = pt_.x;
        *y = pt_.y;
    }

    void move_to(value_type x,value_type y)
    {
        pt_.x = x;
        pt_.y = y;
    }

    void line_to(value_type ,value_type ) {}

    unsigned num_points() const
    {
        return 1;
    }

    unsigned vertex(double* x, double* y) const
    {
        *x = pt_.x;
        *y = pt_.y;
        return SEG_LINETO;
    }

    void rewind(unsigned ) const {}

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_in_circle(pt_.x,pt_.y, x,y,tol);
    }

    void set_capacity(size_t) {}
    virtual ~point() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class polygon //: public geometry<T>
{
public:
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
    typedef Container<vertex_type> container_type;
private:
    container_type cont_;
    mutable unsigned itr_;
public:

    typedef typename container_type::const_iterator iterator;

    iterator begin() const
    {
	return cont_.begin();
    }

    iterator end() const
    {
	return cont_.end();
    }

    polygon()
        : //geometry_base(),
        itr_(0)
    {}

    int type() const
    {
        return Polygon;
    }

    double area() const
    {
        double sum = 0.0;
        double x(0);
        double y(0);
        rewind(0);
        double xs = x;
        double ys = y;
        for (unsigned i=0;i<num_points();++i)
        {
            double x0,y0;
            vertex(&x0,&y0);
            sum += x * y0 - y * x0;
            x = x0;
            y = y0;
        }
        return (sum + x * ys - y * xs) * 0.5;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }
    void label_position(double *x, double *y) const
    {
        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double) const
    {
        return point_inside_path(x,y,cont_.begin(),cont_.end());
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    //virtual ~polygon() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class line_string : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry_base::value_type value_type;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef Container<vertex_type> container_type;
private:
    container_type cont_;
    mutable unsigned itr_;
public:
    line_string()
        : geometry_base(),
          itr_(0)
    {}

    int type() const
    {
        return LineString;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        // calculate mid point on line string
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }
    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    virtual ~line_string() {}
};

//typedef point<vertex2d> point_impl;
//typedef line_string<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> point_impl;
typedef polygon<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> polygon_impl;

typedef polygon_impl geometry2d;
typedef boost::shared_ptr<geometry2d> geometry_ptr;
typedef boost::ptr_vector<geometry2d> geometry_containter;
}

#endif //GEOMETRY_HPP
<|endoftext|>