diff --git a/uppsrc/Geom/Coords/GeomCoords.h b/uppsrc/Geom/Coords/GeomCoords.h index 383bc7c84..39dc77211 100644 --- a/uppsrc/Geom/Coords/GeomCoords.h +++ b/uppsrc/Geom/Coords/GeomCoords.h @@ -432,6 +432,35 @@ private: bool sukneg, cukneg; }; +class SphericalLatitudeFunction : public GisFunction +{ +public: + SphericalLatitudeFunction(double alpha, double k, double R, double e, double U0) + : alpha(alpha), k(k), R(R), e(e), U0(U0) {} + + virtual double Get(double x) const; + +private: + double alpha, k, R, e, U0; +}; + +class GisCoordsGaussLatitude { +public: + GisCoordsGaussLatitude(); + + void Create(double a, double e2, double base_parallel); + + double Spherical(double latitude) const { return gauss_projected(latitude); } + double Elliptical(double latitude) const { return gauss_latitude(latitude); } + +public: + double radius; + +private: + mutable GisInterpolator gauss_projected; + mutable GisInterpolator gauss_latitude; +}; + class GisEllipsoid { public: @@ -451,6 +480,7 @@ public: HAYFORD_1909 = 7022, KRASSOWSKY_1940 = 7024, WGS_1984 = 7030, + GRS_1980 = 7019, }; bool IsNullInstance() const { return !a; } diff --git a/uppsrc/Geom/Coords/init b/uppsrc/Geom/Coords/init index cb45f856b..55b066f01 100644 --- a/uppsrc/Geom/Coords/init +++ b/uppsrc/Geom/Coords/init @@ -1,5 +1,4 @@ #ifndef _Geom_Coords_icpp_init_stub #define _Geom_Coords_icpp_init_stub -#include "TCore/init" #include "Geom/init" #endif diff --git a/uppsrc/Geom/Coords/method.cpp b/uppsrc/Geom/Coords/method.cpp index c4ac8292e..5fcd55300 100644 --- a/uppsrc/Geom/Coords/method.cpp +++ b/uppsrc/Geom/Coords/method.cpp @@ -170,26 +170,6 @@ void GisCoordsSpherical::SyncInterpolator() const gauss_latitude.CreateInverse(-M_PI / 2, +M_PI / 2, gslf, 300, 5000, 4); } -double SphericalLatitudeFunction::Get(double phi) const -{ -// RTIMING("SphericalLatitudeFunction::Get"); - phi *= DEGRAD; - double esx = e * sin(phi); - double eps = pow((1 - esx) / (1 + esx), e * alpha / 2) / k; - double dpi = M_PI / 4 - phi / 2; - if(dpi <= 0.001) - { -// RLOG("first dpi = " << FormatDouble(x, 5)); -// RLOG("saturation: " << dpi); - return 90 - 2 / DEGRAD * (pow(fabs(dpi), alpha) / (dpi >= 0 ? eps : -eps)); - } - else - { - double rho = phi / 2 + M_PI / 4; - return 2 / DEGRAD * atan(pow(fabs(tan(rho)), alpha) * (rho >= 0 ? eps : -eps)) - 90; - } -} - GisCoordsConical::GisCoordsConical( // bool gauss_sphere_, double gauss_base_parallel_, @@ -433,7 +413,7 @@ void GisCoordsConical::SyncArgs() * pow((1 + esin_0) * (1 - esin_n) / ((1 - esin_0) * (1 + esin_n)), n * e / 2); rho_coef = rho0 * pow(tan_0, n) * pow((1 - esin_0) / (1 + esin_0), n * e / 2); */ - SphericalLatitudeFunction gslf(gauss_alpha, gauss_k, gauss_R, gauss_e, gauss_U0); + //SphericalLatitudeFunction gslf(gauss_alpha, gauss_k, gauss_R, gauss_e, gauss_U0); double Us = south_parallel * DEGRAD, Un = north_parallel * DEGRAD, Uc = central_parallel * DEGRAD; double Tn = tan(Un / 2 + M_PI / 4), Ts = tan(Us / 2 + M_PI / 4), Tc = tan(Uc / 2 + M_PI / 4); if(fabs(Un - Us) <= SECRAD) @@ -612,9 +592,19 @@ void GisCoordsUTM::SyncArgs() E12 = sqr(ellipsoid.a / ellipsoid.b) - 1; } -GisCoordsAzimuthal::GisCoordsAzimuthal(Pointf p) +GisCoordsAzimuthal::GisCoordsAzimuthal(const Pointf& p, const Sizef& sc, const Sizef& o) { pole = p; + scale = sc; + offset = o; +} + +GisCoords GisCoordsAzimuthal::DeepCopy() const +{ + One out = new GisCoordsAzimuthal(pole, scale, offset); + out->ellipsoid = ellipsoid; + out->SyncArgs(); + return GisCoords(-out); } int GisCoordsAzimuthal::GetBranchCount() const @@ -634,49 +624,67 @@ GisBSPTree GisCoordsAzimuthal::GetBranchTree(const Rectf& lonlat_extent) const Pointf GisCoordsAzimuthal::LonLat(Pointf xy) const { + xy -= offset; + xy /= scale; double rho = Length(xy); - double eps = atan2(xy.x, -xy.y) / DEGRAD; - double psi = rho / Rdeg; -// return Pointf(eps, M_PI / 2 - psi); - return orientation.Global(eps, 90 - psi); + double eps = Bearing(xy) / DEGRAD; + double sine = min(rho / (2 * gauss.radius), 1.0); + double psi = 2 * asin(sine); + //double psi = rho / Rdeg; + //return Pointf(eps, M_PI / 2 - psi); + Pointf out = orientation.Global(eps, 90 - psi); + //out.y = gauss.Elliptical(out.y); + return out; } +/* Rectf GisCoordsAzimuthal::LonLatExtent(const Rectf& xy_extent) const { Rectf lonlat = ExtentToDegree(xy_extent); return orientation.GlobalExtent(lonlat.left, 90 - lonlat.bottom / Rdeg, lonlat.right, 90 - lonlat.top / Rdeg); } +*/ Pointf GisCoordsAzimuthal::Project(Pointf lonlat, int branch) const { + lonlat.y = gauss.Spherical(lonlat.y); lonlat = orientation.Local(lonlat); - double psi = 90 - lonlat.y; -// double rho = R * E * sin(psi) / (c + R * cos(psi)); - double rho = Rdeg * psi; - return PolarPointf(rho, lonlat.x - 90); + double psi = DEGRAD * (90 - lonlat.y); + //double rho = R * E * sin(psi) / (c + R * cos(psi)); + //double rho = Rdeg * psi; + double rho = 2 * gauss.radius * sin(psi / 2); + return scale * (Sizef)PolarPointf(rho, (lonlat.x - 90) * DEGRAD) + offset; } +/* Rectf GisCoordsAzimuthal::ProjectExtent(const Rectf& lonlat_extent) const { Rectf local = orientation.LocalExtent(lonlat_extent); return DegreeToExtent(local.left, Rdeg * (90 - local.bottom), local.right, Rdeg * (90 - local.top)); } +*/ +/* double GisCoordsAzimuthal::ProjectDeviation(Pointf lonlat1, Pointf lonlat2, int branch) const { return 0; } +*/ +/* double GisCoordsAzimuthal::ProjectRatio(Pointf lonlat, int branch) const { return 1; } +*/ Array GisCoordsAzimuthal::EnumArgs() { Array out; out.Add(GisCoords::Arg::Angle(pole.x, "POLE_M", "Pole meridian", "", -180, +180)); out.Add(GisCoords::Arg::Angle(pole.y, "POLE_P", "Pole parallel", "", -90, +90)); + out.Add(GisCoords::Arg::Edit(offset.cx, "X_OFFSET", "False easting")); + out.Add(GisCoords::Arg::Edit(offset.cy, "Y_OFFSET", "False northing")); return out; } @@ -688,11 +696,9 @@ Array GisCoordsAzimuthal::EnumConstArgs() const void GisCoordsAzimuthal::SyncArgs() { - orientation = pole; - R = 6378e3; - Rdeg = R * DEGRAD; - c = R * 1.7; - E = 1; + gauss.Create(ellipsoid.a, ellipsoid.e2, pole.y); + gauss.radius = 6384000; + orientation = Pointf(pole.x, gauss.Spherical(pole.y)); } void GisCoordsAzimuthal::SyncInterpolator() const @@ -705,6 +711,7 @@ const Vector& GisCoords::EnumEPSG() if(epsg.IsEmpty()) epsg << 2065 // JTSK + << 3035 // ETRS89 / ETRS-LAEA << 4326 // WGS-84 << 4818 // JTSK-geo << 28403 // S-42 @@ -753,6 +760,40 @@ GisCoords GisCoords::GetEPSG(int code) "UNIT[\"metre\",1]]"; break; + case 3035: { + gc = new GisCoordsAzimuthal( + Pointf(10, 52), + Sizef(1, 1), + Sizef(4321000, 3210000)); + gc->ellipsoid = GisEllipsoid::GetEPSG(GisEllipsoid::WGS_1984); //GRS_1980); + gc->name = "ETRS89 / ETRS-LAEA"; + gc->description = "Single CRS for all Europe"; + gc->coordsys = + "PROJCS[\"ETRS89 / ETRS-LAEA\"," + "GEOGCS[\"ETRS89\"," + "DATUM[\"European_Terrestrial_Reference_System_1989\"," + "SPHEROID[\"GRS 1980\",6378137,298.257222101," + "AUTHORITY[\"EPSG\",\"7019\"]]," + "AUTHORITY[\"EPSG\",\"6258\"]]," + "PRIMEM[\"Greenwich\",0," + "AUTHORITY[\"EPSG\",\"8901\"]]," + "UNIT[\"degree\",0.01745329251994328," + "AUTHORITY[\"EPSG\",\"9122\"]]," + "AUTHORITY[\"EPSG\",\"4258\"]]," + "UNIT[\"metre\",1," + "AUTHORITY[\"EPSG\",\"9001\"]]," + "PROJECTION[\"Lambert_Azimuthal_Equal_Area\"]," + "PARAMETER[\"latitude_of_center\",52]," + "PARAMETER[\"longitude_of_center\",10]," + "PARAMETER[\"false_easting\",4321000]," + "PARAMETER[\"false_northing\",3210000]," + "AUTHORITY[\"EPSG\",\"3035\"]," + "AXIS[\"X\",EAST]," + "AXIS[\"Y\",NORTH]]" + ; + break; + } + case 4326: gc = new GisCoordsLonLat(0); gc->ellipsoid = GisEllipsoid::GetEPSG(GisEllipsoid::WGS_1984); @@ -806,6 +847,9 @@ GisCoords GisCoords::GetEPSG(int code) "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]], " "AUTHORITY[\"EPSG\",\"2166\"]]"; break; + + default: + return GisCoords(); } gc->ident = NFormat("EPSG:%d", code); gc->SyncArgs(); diff --git a/uppsrc/Geom/Coords/method.h b/uppsrc/Geom/Coords/method.h index 4a462a616..18c558076 100644 --- a/uppsrc/Geom/Coords/method.h +++ b/uppsrc/Geom/Coords/method.h @@ -33,18 +33,6 @@ public: double base_parallel; }; -class SphericalLatitudeFunction : public GisFunction -{ -public: - SphericalLatitudeFunction(double alpha, double k, double R, double e, double U0) - : alpha(alpha), k(k), R(R), e(e), U0(U0) {} - - virtual double Get(double x) const; - -private: - double alpha, k, R, e, U0; -}; - class GisCoordsSpherical : public GisCoords::Data , public GisCoordsSphericalData { @@ -203,21 +191,22 @@ class GisCoordsAzimuthal : public GisCoords::Data { public: typedef GisCoordsAzimuthal CLASSNAME; - GisCoordsAzimuthal(Pointf pole = Pointf(0, 90)); + GisCoordsAzimuthal(const Pointf& pole = Pointf(0, 90), + const Sizef& scale = Sizef(1, 1), const Sizef& offset = Sizef(0, 0)); // GisCoordsAzimuthal(const GisCoordsAzimuthal& a) - virtual GisCoords DeepCopy() const { return new GisCoordsAzimuthal(*this); } + virtual GisCoords DeepCopy() const; virtual int GetBranchCount() const; virtual Array LonLatBoundary(const Rectf& lonlat_extent, int branch) const; virtual GisBSPTree GetBranchTree(const Rectf& lonlat_extent) const; virtual Pointf LonLat(Pointf xy) const; - virtual Rectf LonLatExtent(const Rectf& xy_extent) const; + //virtual Rectf LonLatExtent(const Rectf& xy_extent) const; virtual Pointf Project(Pointf lonlat, int branch) const; - virtual Rectf ProjectExtent(const Rectf& lonlat_extent) const; - virtual double ProjectDeviation(Pointf lonlat1, Pointf lonlat2, int branch) const; - virtual double ProjectRatio(Pointf lonlat, int branch) const; + //virtual Rectf ProjectExtent(const Rectf& lonlat_extent) const; + //virtual double ProjectDeviation(Pointf lonlat1, Pointf lonlat2, int branch) const; + //virtual double ProjectRatio(Pointf lonlat, int branch) const; // virtual String ToString() const; virtual Array EnumArgs(); @@ -230,8 +219,11 @@ private: public: Pointf pole; + Pointf gauss_pole; + Sizef scale; + Sizef offset; GisOrientation orientation; - double R, Rdeg, E, c; + GisCoordsGaussLatitude gauss; }; END_UPP_NAMESPACE diff --git a/uppsrc/Geom/Coords/util.cpp b/uppsrc/Geom/Coords/util.cpp index aecf28bb1..899a2e4d8 100644 --- a/uppsrc/Geom/Coords/util.cpp +++ b/uppsrc/Geom/Coords/util.cpp @@ -1337,4 +1337,52 @@ PlanarSegmentTree CreatePlanarTree(const LinearSegmentTree& left, const LinearSe return out; } +GisCoordsGaussLatitude::GisCoordsGaussLatitude() +{ +} + +double SphericalLatitudeFunction::Get(double phi) const +{ +// RTIMING("SphericalLatitudeFunction::Get"); + phi *= DEGRAD; + double esx = e * sin(phi); + double eps = pow((1 - esx) / (1 + esx), e * alpha / 2) / k; + double dpi = M_PI / 4 - phi / 2; + if(dpi <= 0.001) + { +// RLOG("first dpi = " << FormatDouble(x, 5)); +// RLOG("saturation: " << dpi); + return 90 - 2 / DEGRAD * (pow(fabs(dpi), alpha) / (dpi >= 0 ? eps : -eps)); + } + else + { + double rho = phi / 2 + M_PI / 4; + return 2 / DEGRAD * atan(pow(fabs(tan(rho)), alpha) * (rho >= 0 ? eps : -eps)) - 90; + } +} + +void GisCoordsGaussLatitude::Create(double a, double e2, double base_parallel) +{ + double e = sqrt(e2); + double phi0 = base_parallel * DEGRAD; + double alpha = sqrt(1 + (e2 * sqr(sqr(cos(phi0)))) / (1 - e2)); + double sinphi = sin(phi0); + double U0 = asin(sinphi / alpha); + double k = exp(alpha * (log(tan(phi0 / 2 + M_PI / 4)) + e / 2 * log((1 - e * sinphi) / (1 + e * sinphi)))) + / tan(U0 / 2 + M_PI / 4); +// k = pow(tan(base_parallel / 2 + M_PI / 4), alpha) +// * pow((1 - e * sinphi) / (1 + e * sinphi), alpha * e / 2) +// / tan(U0 / 2 + M_PI / 4); + radius = a * sqrt(1 - e2) / (1 - e2 * sqr(sinphi)); + gauss_projected.Clear(); + gauss_latitude.Clear(); + + SphericalLatitudeFunction gslf(alpha, k, radius, e, U0); + //gslf.Dump(-1.58, +1.58, 1000); + //gslf.Dump(-1.58, -1.56, 1000); + //gslf.Dump(+1.56, +1.58, 1000); + gauss_projected.Create(base_parallel - 30, base_parallel + 30, gslf, 300, 5000, 4); + gauss_latitude.CreateInverse(base_parallel - 30, base_parallel + 30, gslf, 300, 5000, 4); +} + END_UPP_NAMESPACE diff --git a/uppsrc/TCore/CalcBasic.cpp b/uppsrc/TCore/CalcBasic.cpp index c724377dc..28d62f3a0 100644 --- a/uppsrc/TCore/CalcBasic.cpp +++ b/uppsrc/TCore/CalcBasic.cpp @@ -343,7 +343,7 @@ inline String CtextD(CalcPacket& packet, Time d) FDECLP(text, S, &GroupString) FDECLAP(text, D, &GroupString) -inline String CtextA(CalcPacket& packet, ValueArray va) +inline String CtextA(CalcPacket& packet, const ValueArray& va) { String out; out << "["; @@ -747,11 +747,11 @@ inline bool CalcArrayCtr(CalcPacket& packet) packet.args.Add("..."); return true; } - ValueArray va; - va.SetCount(packet.args.GetCount()); + Vector vlist; + vlist.SetCount(packet.args.GetCount()); for(int i = 0; i < packet.args.GetCount(); i++) - va.Set(i, packet.args[i]); - packet.result = va; + vlist[i] = packet.args[i]; + packet.result = ValueArray(vlist); return true; } @@ -764,17 +764,17 @@ inline ValueArray CarrayRange(double lo, double hi) return ValueArray(); if(df >= 1000000) throw Exc(NFormat(t_("array is too long (%d elements)"), df)); - ValueArray va; + Vector vlist; int nelem = fround(df); - va.SetCount(nelem); + vlist.SetCount(nelem); for(int i = 0; i < nelem; i++) - va.Set(i, i + lr); - return va; + vlist[i] = i + lr; + return ValueArray(vlist); } FDECL("[..]", CarrayRange, &GroupArray) -inline Value CarrayIndex(ValueArray va, int index) +inline Value CarrayIndex(const ValueArray& va, int index) { if(index < 0 || index >= va.GetCount()) throw Exc(NFormat(t_("invalid index %d, array has just %d elements"), index, va.GetCount())); @@ -792,18 +792,18 @@ static String CstringIndex(String s, int index) FDECL("[]", CstringIndex, &GroupString) -inline ValueArray CaddAA(ValueArray a, ValueArray b) +inline ValueArray CaddAA(const ValueArray& a, const ValueArray& b) { int ac = a.GetCount(), bc = b.GetCount(); - ValueArray out = a; - out.SetCount(ac + bc); - for(int i = 0; i < bc; i++) - out.Set(i + ac, b[i]); - return out; + Vector out; + out.Reserve(ac + bc); + out.Append(a.Get()); + out.Append(b.Get()); + return ValueArray(out); } FDECL("+", CaddAA, &GroupArray) -inline Value CsumA(CalcPacket& packet, ValueArray a) +inline Value CsumA(CalcPacket& packet, const ValueArray& a) { int i = 0; while(i < a.GetCount() && IsNull(a[i])) @@ -843,8 +843,7 @@ inline Value CsumA(CalcPacket& packet, ValueArray a) for(; i < a.GetCount(); i++) if(IsNull(a[i])) ; - else if(IsValueArray(a[i])) - { + else if(IsValueArray(a[i])) { ValueArray ai = a[i]; for(int t = 0, nt = ai.GetCount(); t < nt; t++) va.Add(ai[t]); @@ -859,11 +858,11 @@ inline Value CsumA(CalcPacket& packet, ValueArray a) FDECLAP(sum, A, &GroupArray) -inline Value CsumASC(CalcPacket& packet, ValueArray va, String var, const CalcNode *node) +inline Value CsumASC(CalcPacket& packet, const ValueArray& va, String var, const CalcNode *node) { if(IsNull(var)) throw Exc(t_("control variable has empty name")); - ValueArray vout; + Vector vout; vout.SetCount(va.GetCount()); if(node) { @@ -871,38 +870,36 @@ inline Value CsumASC(CalcPacket& packet, ValueArray va, String var, const CalcNo for(int i = 0; i < va.GetCount(); i++) { packet.context.Set(var, va[i]); - vout.Set(i, node -> Calc(packet.context)); + vout[i] = node -> Calc(packet.context); } } - return CsumA(packet, vout); + return CsumA(packet, ValueArray(vout)); } FDECLAP(sum, ASC, &GroupArray) -inline ValueArray CmulAC(CalcPacket& packet, ValueArray va, const CalcNode *node) +inline ValueArray CmulAC(CalcPacket& packet, const ValueArray& va, const CalcNode *node) { - ValueArray vout; + Vector vout; vout.SetCount(va.GetCount()); - if(node) - { + if(node) { CalcContext::Nesting level(packet.context); static const String i_("I"), a_("A"); - for(int i = 0; i < va.GetCount(); i++) - { + for(int i = 0; i < va.GetCount(); i++) { packet.context.Set(i_, i); packet.context.Set(a_, va[i]); - vout.Set(i, node -> Calc(packet.context)); + vout[i] = node -> Calc(packet.context); } } - return vout; + return ValueArray(vout); } FDECLA("*", CmulAC, &GroupArray) -inline int CcountA(ValueArray va) { return va.GetCount(); } +inline int CcountA(const ValueArray& va) { return va.GetCount(); } FDECLP(count, A, &GroupArray) -inline Value CmaxA(CalcPacket& packet, ValueArray va) +inline Value CmaxA(CalcPacket& packet, const ValueArray& va) { Value out = Null; for(int i = 0; i < va.GetCount(); i++) @@ -914,7 +911,7 @@ inline Value CmaxA(CalcPacket& packet, ValueArray va) FDECLAP(max, A, &GroupArray) -inline Value CminA(CalcPacket& packet, ValueArray va) +inline Value CminA(CalcPacket& packet, const ValueArray& va) { Value out = Null; for(int i = 0; i < va.GetCount(); i++) @@ -926,7 +923,7 @@ inline Value CminA(CalcPacket& packet, ValueArray va) FDECLAP(min, A, &GroupArray) -inline double CavgA(ValueArray va) +inline double CavgA(const ValueArray& va) { double sum = 0; int cnt = 0; @@ -944,7 +941,7 @@ inline double CavgA(ValueArray va) FDECLP(avg, A, &GroupArray) -inline ValueArray CleftAN(ValueArray va, int count) +inline ValueArray CleftAN(const ValueArray& va, int count) { if(count < 0 || count > va.GetCount()) throw Exc(t_("invalid number of array elements")); @@ -955,7 +952,7 @@ inline ValueArray CleftAN(ValueArray va, int count) } FDECLP(left, AN, &GroupArray) -inline ValueArray CrightAN(ValueArray va, int count) +inline ValueArray CrightAN(const ValueArray& va, int count) { if(count < 0 || count > va.GetCount()) throw Exc(t_("invalid number of array elements")); @@ -966,7 +963,7 @@ inline ValueArray CrightAN(ValueArray va, int count) } FDECLP(right, AN, &GroupArray) -inline ValueArray CmidANN(ValueArray va, int first, int count) +inline ValueArray CmidANN(const ValueArray& va, int first, int count) { if(first < 0 || first > va.GetCount()) throw Exc(t_("invalid character index")); @@ -979,13 +976,13 @@ inline ValueArray CmidANN(ValueArray va, int first, int count) } FDECLP(mid, ANN, &GroupArray) -inline ValueArray CmidAN(ValueArray va, int first) +inline ValueArray CmidAN(const ValueArray& va, int first) { return CmidANN(va, first, va.GetCount() - first); } FDECLP(mid, AN, &GroupArray) -inline bool CinVA(Value v, ValueArray va) +inline bool CinVA(Value v, const ValueArray& va) { for(int i = 0; i < va.GetCount(); i++) if(v == va[i]) @@ -994,14 +991,14 @@ inline bool CinVA(Value v, ValueArray va) } FDECLP(in, VA, &GroupArray) -inline ValueArray CindexA(ValueArray a) +inline ValueArray CindexA(const ValueArray& a) { - ValueArray out; + Vector out; int n = a.GetCount(); out.SetCount(n); for(int i = 0; i < n; i++) - out.Set(i, i); - return out; + out[i] = i; + return ValueArray(out); } FDECLP(index, A, &GroupArray) @@ -1011,7 +1008,7 @@ struct ValueLess { int language; }; -inline ValueArray CsortA(CalcPacket& packet, ValueArray a) +inline ValueArray CsortA(CalcPacket& packet, const ValueArray& a) { if(a.GetCount() <= 1) return a; @@ -1022,7 +1019,7 @@ inline ValueArray CsortA(CalcPacket& packet, ValueArray a) } FDECLAP(sort, A, &GroupArray) -inline ValueArray CsortASC(CalcPacket& packet, ValueArray a, String ident, const CalcNode *lambda) +inline ValueArray CsortASC(CalcPacket& packet, const ValueArray& a, String ident, const CalcNode *lambda) { if(a.GetCount() <= 1) return a; @@ -1040,7 +1037,7 @@ inline ValueArray CsortASC(CalcPacket& packet, ValueArray a, String ident, const } FDECLAP(sort, ASC, &GroupArray) -inline ValueArray CdistinctA(ValueArray a) +inline ValueArray CdistinctA(const ValueArray& a) { if(a.GetCount() <= 1) return a; @@ -1051,7 +1048,7 @@ inline ValueArray CdistinctA(ValueArray a) } FDECLP(distinct, A, &GroupArray) -inline ValueArray CdistinctASC(CalcPacket& packet, ValueArray a, String ident, const CalcNode *lambda) +inline ValueArray CdistinctASC(CalcPacket& packet, const ValueArray& a, String ident, const CalcNode *lambda) { if(a.GetCount() <= 1) return a; @@ -1092,7 +1089,7 @@ static bool CwithVSRC(CalcPacket& packet) FDECLQ("CwithVSRC", "with", &GroupSystem, &CwithVSRC) -static ValueArray CgroupAASCC(CalcPacket& packet, ValueArray data, ValueArray ctrl, String var, +static ValueArray CgroupAASCC(CalcPacket& packet, const ValueArray& data, ValueArray ctrl, String var, const CalcNode *grp, const CalcNode *val) { Index ix(ctrl.Get(), 0); @@ -1130,7 +1127,8 @@ static ValueArray CgroupAASCC(CalcPacket& packet, ValueArray data, ValueArray ct FDECLAP(group, AASCC, &GroupArray) -static ValueArray CgroupAASC(CalcPacket& packet, ValueArray data, ValueArray ctrl, String var, const CalcNode *grp) +static ValueArray CgroupAASC(CalcPacket& packet, const ValueArray& data, + const ValueArray& ctrl, String var, const CalcNode *grp) { return CgroupAASCC(packet, data, ctrl, var, grp, NULL); }