Program Listing for File CRSDistance.h

Return to documentation for file (include/gwmodelpp/spatialweight/CRSDistance.h)

#ifndef CRSDISTANCE_H
#define CRSDISTANCE_H

#include "Distance.h"

namespace gwm
{

class CRSDistance : public Distance
{
public:

    struct Parameter : public Distance::Parameter
    {
        arma::mat focusPoints;

        arma::mat dataPoints;

        Parameter(const arma::mat& fp, const arma::mat& dp) : Distance::Parameter()
            , focusPoints(fp)
            , dataPoints(dp)
        {
            total = fp.n_rows;
        }
    };

public:

    static arma::vec SpatialDistance(const arma::rowvec& out_loc, const arma::mat& in_locs);

    static arma::vec EuclideanDistance(const arma::rowvec& out_loc, const arma::mat& in_locs)
    {
        arma::mat diff = (in_locs.each_row() - out_loc);
        return sqrt(sum(diff % diff, 1));
    }

    static double SpGcdist(double lon1, double lon2, double lat1, double lat2);

private:
    typedef arma::vec (*CalculatorType)(const arma::rowvec&, const arma::mat&);

public:

    CRSDistance() : mGeographic(false), mParameter(nullptr) {}

    explicit CRSDistance(bool isGeographic): mGeographic(isGeographic), mParameter(nullptr)
    {
        mCalculator = mGeographic ? &SpatialDistance : &EuclideanDistance;
    }

    CRSDistance(const CRSDistance& distance);

    virtual Distance * clone() override
    {
        return new CRSDistance(*this);
    }

    DistanceType type() override { return DistanceType::CRSDistance; }

    bool geographic() const
    {
        return mGeographic;
    }

    void setGeographic(bool geographic)
    {
        mGeographic = geographic;
        mCalculator = mGeographic ? &SpatialDistance : &EuclideanDistance;
    }

public:

    virtual void makeParameter(std::initializer_list<DistParamVariant> plist) override;

    virtual arma::vec distance(arma::uword focus) override;
    virtual double maxDistance() override;
    virtual double minDistance() override;

protected:
    bool mGeographic;
    std::unique_ptr<Parameter> mParameter;

private:
    CalculatorType mCalculator = &EuclideanDistance;
};

}

#endif // CRSDISTANCE_H