1388 lines
38 KiB
C++
1388 lines
38 KiB
C++
|
|
/*
|
||
|
|
\newpage
|
||
|
|
|
||
|
|
----
|
||
|
|
This file is part of SECONDO.
|
||
|
|
|
||
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
||
|
|
Database Systems for New Applications.
|
||
|
|
|
||
|
|
SECONDO is free software; you can redistribute it and/or modify
|
||
|
|
it under the terms of the GNU General Public License as published by
|
||
|
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
|
(at your option) any later version.
|
||
|
|
|
||
|
|
SECONDO 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 General Public License for more details.
|
||
|
|
|
||
|
|
You should have received a copy of the GNU General Public License
|
||
|
|
along with SECONDO; if not, write to the Free Software
|
||
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
----
|
||
|
|
|
||
|
|
//[_] [\_]
|
||
|
|
//characters [1] verbatim: [$] [$]
|
||
|
|
//characters [2] formula: [$] [$]
|
||
|
|
//characters [3] capital: [\textsc{] [}]
|
||
|
|
//characters [4] teletype: [\texttt{] [}]
|
||
|
|
|
||
|
|
1 Implementation file "GeneralTreeAlgebra.cpp"[4]
|
||
|
|
|
||
|
|
January-May 2008, Mirko Dibbert
|
||
|
|
|
||
|
|
This file implements the GeneralTreeAlgebra.
|
||
|
|
|
||
|
|
1.1 Includes and defines.
|
||
|
|
|
||
|
|
*/
|
||
|
|
#include "Algebra.h"
|
||
|
|
#include "Algebras/Relation-C++/RelationAlgebra.h"
|
||
|
|
#include "NestedList.h"
|
||
|
|
#include "QueryProcessor.h"
|
||
|
|
#include "Base64.h"
|
||
|
|
#include "Symbols.h"
|
||
|
|
|
||
|
|
#include "GeneralTreeAlgebra.h"
|
||
|
|
|
||
|
|
extern NestedList *nl;
|
||
|
|
extern QueryProcessor *qp;
|
||
|
|
extern AlgebraManager *am;
|
||
|
|
|
||
|
|
using namespace std;
|
||
|
|
|
||
|
|
namespace gta {
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1. Type constructors
|
||
|
|
|
||
|
|
1.1.1 Type constructor "hpoint"[4]
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
static ListExpr HPointProp()
|
||
|
|
{
|
||
|
|
return (
|
||
|
|
nl->TwoElemList(
|
||
|
|
nl->FourElemList(
|
||
|
|
nl->StringAtom("Signature"),
|
||
|
|
nl->StringAtom("Example Type List"),
|
||
|
|
nl->StringAtom("List Rep"),
|
||
|
|
nl->StringAtom("Example List")),
|
||
|
|
nl->FourElemList(
|
||
|
|
nl->StringAtom("-> DATA"),
|
||
|
|
nl->StringAtom(HPoint::BasicType()),
|
||
|
|
nl->StringAtom("(<dim> (<c_1> ... <c_n>) "),
|
||
|
|
nl->StringAtom("(2 (0.5 2.5))"))));
|
||
|
|
}
|
||
|
|
|
||
|
|
ListExpr OutHPoint(ListExpr type_Info, Word value)
|
||
|
|
{
|
||
|
|
HPoint* point = static_cast<HPointAttr*>(value.addr)->hpoint();
|
||
|
|
NList coord_list;
|
||
|
|
|
||
|
|
for (unsigned i = 0; i < point->dim(); ++i)
|
||
|
|
coord_list.append(NList(point->coord(i)));
|
||
|
|
|
||
|
|
NList dim_list(static_cast<int>(point->dim()));
|
||
|
|
NList result(dim_list, coord_list);
|
||
|
|
delete point;
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
Word InHPoint(
|
||
|
|
ListExpr type_Info, ListExpr value,
|
||
|
|
int errorPos, ListExpr &_error_Info, bool &corect)
|
||
|
|
{
|
||
|
|
NList valueList(value);
|
||
|
|
|
||
|
|
if (valueList.length() != 2)
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a two elemental list, but got" +
|
||
|
|
valueList.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
NList dim_list = valueList.first();
|
||
|
|
NList coords_list = valueList.second();
|
||
|
|
|
||
|
|
unsigned dim;
|
||
|
|
if (!dim_list.isInt())
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted an int atom as first list element, but got " +
|
||
|
|
dim_list.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
dim = dim_list.intval();
|
||
|
|
|
||
|
|
if (coords_list.length() != dim)
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ostringstream error;
|
||
|
|
error << "Excepted a list with " << dim
|
||
|
|
<< " real values as second list element, but got "
|
||
|
|
<< coords_list.convertToString();
|
||
|
|
ErrorReporter::ReportError(error.str());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
GTA_SPATIAL_DOM coords[dim];
|
||
|
|
int pos = 0;
|
||
|
|
while (!coords_list.isEmpty())
|
||
|
|
{
|
||
|
|
NList coord = coords_list.first();
|
||
|
|
coords_list.rest();
|
||
|
|
|
||
|
|
if (!coord.isReal())
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted an real atom as list element, but got " +
|
||
|
|
coord.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
coords[pos] = nl->RealValue(coord.listExpr());
|
||
|
|
|
||
|
|
pos++;
|
||
|
|
}
|
||
|
|
|
||
|
|
corect = true;
|
||
|
|
return SetWord(new HPointAttr(dim, coords));
|
||
|
|
}
|
||
|
|
|
||
|
|
Word createHPoint(const ListExpr type_Info)
|
||
|
|
{ return SetWord(new HPointAttr(0)); }
|
||
|
|
|
||
|
|
void DeleteHPoint(const ListExpr type_Info, Word &w)
|
||
|
|
{
|
||
|
|
HPointAttr* attr = static_cast<HPointAttr*>(w.addr);
|
||
|
|
attr->deleteFLOB();
|
||
|
|
delete attr;
|
||
|
|
w.addr = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool OpenHPoint(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word &value)
|
||
|
|
{
|
||
|
|
value = SetWord(Attribute::Open(valueRecord, offset, type_Info));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SaveHPoint(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word &value)
|
||
|
|
{
|
||
|
|
Attribute::Save(
|
||
|
|
valueRecord, offset, type_Info,
|
||
|
|
static_cast<Attribute*>(value.addr));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CloseHPoint(const ListExpr type_Info, Word &w)
|
||
|
|
{ delete(HPointAttr*)w.addr; }
|
||
|
|
|
||
|
|
Word CloneHPoint(const ListExpr type_Info, const Word &w)
|
||
|
|
{
|
||
|
|
HPointAttr *src = static_cast<HPointAttr*>(w.addr);
|
||
|
|
HPointAttr *cpy = new HPointAttr(*src);
|
||
|
|
return SetWord(cpy);
|
||
|
|
}
|
||
|
|
|
||
|
|
void * CastHPoint(void *addr)
|
||
|
|
{ return new(addr) HPointAttr; }
|
||
|
|
|
||
|
|
int SizeOfHPoint()
|
||
|
|
{ return sizeof(HPointAttr); }
|
||
|
|
|
||
|
|
bool CheckHPoint(ListExpr typeName, ListExpr &error_Info)
|
||
|
|
{ return (nl->IsEqual(typeName, HPoint::BasicType())); }
|
||
|
|
|
||
|
|
TypeConstructor hpoint_tc(
|
||
|
|
HPoint::BasicType(), HPointProp,
|
||
|
|
OutHPoint, InHPoint,
|
||
|
|
0, 0,
|
||
|
|
createHPoint, DeleteHPoint,
|
||
|
|
OpenHPoint, SaveHPoint,
|
||
|
|
CloseHPoint, CloneHPoint,
|
||
|
|
CastHPoint, SizeOfHPoint,
|
||
|
|
CheckHPoint);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1.1 Type constructor "hrect"[4]
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
static ListExpr HRectProp()
|
||
|
|
{
|
||
|
|
return (
|
||
|
|
nl->TwoElemList(
|
||
|
|
nl->FourElemList(
|
||
|
|
nl->StringAtom("Signature"),
|
||
|
|
nl->StringAtom("Example Type List"),
|
||
|
|
nl->StringAtom("List Rep"),
|
||
|
|
nl->StringAtom("Example List")),
|
||
|
|
nl->FourElemList(
|
||
|
|
nl->StringAtom("-> DATA"),
|
||
|
|
nl->StringAtom(HRect::BasicType()),
|
||
|
|
nl->StringAtom("(<dim> (<lb_1> ... <lb_n>) "
|
||
|
|
"(<ub_1> ... <ub_n>))"),
|
||
|
|
nl->StringAtom("(2 (0.0 0.0) (1.0 1.0))"))));
|
||
|
|
}
|
||
|
|
|
||
|
|
ListExpr OutHRect(ListExpr type_Info, Word value)
|
||
|
|
{
|
||
|
|
HRect *rect = static_cast<HRectAttr*>(value.addr)->hrect();
|
||
|
|
NList lb_list, ub_list;
|
||
|
|
|
||
|
|
for (unsigned i = 0; i < rect->dim(); ++i)
|
||
|
|
{
|
||
|
|
lb_list.append(NList(rect->lb(i)));
|
||
|
|
ub_list.append(NList(rect->ub(i)));
|
||
|
|
}
|
||
|
|
|
||
|
|
NList dim_list(static_cast<int>(rect->dim()));
|
||
|
|
NList result(dim_list, lb_list, ub_list);
|
||
|
|
delete rect;
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
Word InHRect(
|
||
|
|
ListExpr type_Info, ListExpr value,
|
||
|
|
int errorPos, ListExpr &_error_Info, bool &corect)
|
||
|
|
{
|
||
|
|
NList valueList(value);
|
||
|
|
|
||
|
|
if (valueList.length() != 3)
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a three elemental list, but got" +
|
||
|
|
valueList.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
NList dim_list = valueList.first();
|
||
|
|
NList lb_list = valueList.second();
|
||
|
|
NList ub_list = valueList.third();
|
||
|
|
|
||
|
|
unsigned dim;
|
||
|
|
if (!dim_list.isInt())
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted an int atom as first list element, but got " +
|
||
|
|
dim_list.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
dim = dim_list.intval();
|
||
|
|
|
||
|
|
if (lb_list.length() != dim)
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ostringstream error;
|
||
|
|
error << "Excepted a list with " << dim
|
||
|
|
<< " real values as second list element, but got "
|
||
|
|
<< lb_list.convertToString();
|
||
|
|
ErrorReporter::ReportError(error.str());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ub_list.length() != dim)
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ostringstream error;
|
||
|
|
error << "Excepted a list with " << dim
|
||
|
|
<< " real values as third list element, but got "
|
||
|
|
<< ub_list.convertToString();
|
||
|
|
ErrorReporter::ReportError(error.str());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
GTA_SPATIAL_DOM lbVector[dim], ubVector[dim];
|
||
|
|
int pos = 0;
|
||
|
|
while (!lb_list.isEmpty())
|
||
|
|
{
|
||
|
|
NList lb = lb_list.first();
|
||
|
|
NList ub = ub_list.first();
|
||
|
|
lb_list.rest();
|
||
|
|
ub_list.rest();
|
||
|
|
|
||
|
|
if (!lb.isReal())
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted an real atom as list element, but got " +
|
||
|
|
lb.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
lbVector[pos] = nl->RealValue(lb.listExpr());
|
||
|
|
|
||
|
|
if (!ub.isReal())
|
||
|
|
{
|
||
|
|
corect = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted an real atom as list element, but got " +
|
||
|
|
ub.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
ubVector[pos] = nl->RealValue(ub.listExpr());
|
||
|
|
|
||
|
|
pos++;
|
||
|
|
}
|
||
|
|
|
||
|
|
corect = true;
|
||
|
|
return SetWord(new HRectAttr(dim, lbVector, ubVector));
|
||
|
|
}
|
||
|
|
|
||
|
|
Word createHRect(const ListExpr type_Info)
|
||
|
|
{ return SetWord(new HRectAttr(0)); }
|
||
|
|
|
||
|
|
void DeleteHRect(const ListExpr type_Info, Word &w)
|
||
|
|
{
|
||
|
|
HRectAttr *attr =
|
||
|
|
static_cast<HRectAttr*>(w.addr);
|
||
|
|
attr->deleteFLOB();
|
||
|
|
delete attr;
|
||
|
|
w.addr = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool OpenHRect(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word &value)
|
||
|
|
{
|
||
|
|
value = SetWord(Attribute::Open(valueRecord, offset, type_Info));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SaveHRect(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word &value)
|
||
|
|
{
|
||
|
|
Attribute::Save(
|
||
|
|
valueRecord, offset, type_Info,
|
||
|
|
static_cast<Attribute*>(value.addr));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CloseHRect(const ListExpr type_Info, Word &w)
|
||
|
|
{ delete(HRectAttr*)w.addr; }
|
||
|
|
|
||
|
|
Word CloneHRect(const ListExpr type_Info, const Word &w)
|
||
|
|
{
|
||
|
|
HRectAttr *src = static_cast<HRectAttr*>(w.addr);
|
||
|
|
HRectAttr *cpy = new HRectAttr(*src);
|
||
|
|
return SetWord(cpy);
|
||
|
|
}
|
||
|
|
|
||
|
|
void * CastHRect(void *addr)
|
||
|
|
{ return new(addr) HRectAttr; }
|
||
|
|
|
||
|
|
int SizeOfHRect()
|
||
|
|
{ return sizeof(HRectAttr); }
|
||
|
|
|
||
|
|
bool CheckHRect(ListExpr typeName, ListExpr &error_Info)
|
||
|
|
{ return (nl->IsEqual(typeName, HRect::BasicType())); }
|
||
|
|
|
||
|
|
TypeConstructor hrect_tc(
|
||
|
|
HRect::BasicType(), HRectProp,
|
||
|
|
OutHRect, InHRect,
|
||
|
|
0, 0,
|
||
|
|
createHRect, DeleteHRect,
|
||
|
|
OpenHRect, SaveHRect,
|
||
|
|
CloseHRect, CloneHRect,
|
||
|
|
CastHRect, SizeOfHRect,
|
||
|
|
CheckHRect);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1 Type constructor "distdata"[4]
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
static ListExpr DistDataProp()
|
||
|
|
{
|
||
|
|
return (nl->TwoElemList(
|
||
|
|
nl->FourElemList(nl->StringAtom("Signature"),
|
||
|
|
nl->StringAtom("Example Type List"),
|
||
|
|
nl->StringAtom("List Rep"),
|
||
|
|
nl->StringAtom("Example List")),
|
||
|
|
nl->FourElemList(nl->StringAtom("-> DATA"),
|
||
|
|
nl->StringAtom(DistDataAttribute::BasicType()),
|
||
|
|
nl->StringAtom("no list, use operator"
|
||
|
|
" getdistdata"),
|
||
|
|
nl->StringAtom("---"))));
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
ListExpr OutDistData(ListExpr type_Info, Word value)
|
||
|
|
{
|
||
|
|
DistDataAttribute* ddAttr =
|
||
|
|
static_cast<DistDataAttribute*>(value.addr);
|
||
|
|
Base64 b64;
|
||
|
|
string b64string;
|
||
|
|
char * data = ddAttr->getData();
|
||
|
|
b64.encode(data, ddAttr->size(), b64string);
|
||
|
|
delete[] data;
|
||
|
|
DistDataInfo info = DistDataReg::
|
||
|
|
getInfo(ddAttr->distdataId());
|
||
|
|
|
||
|
|
string name = info.name();
|
||
|
|
string type = info.typeName();
|
||
|
|
|
||
|
|
// remove lf from b64string
|
||
|
|
b64string = b64string.substr(0, b64string.size() - 1);
|
||
|
|
|
||
|
|
return nl->ThreeElemList(
|
||
|
|
nl->StringAtom(type),
|
||
|
|
nl->StringAtom(name),
|
||
|
|
nl->TextAtom(b64string));
|
||
|
|
}
|
||
|
|
|
||
|
|
Word InDistData(
|
||
|
|
ListExpr type_Info, ListExpr value,
|
||
|
|
int errorPos, ListExpr &error_Info, bool &correct)
|
||
|
|
{
|
||
|
|
NList valueList(value);
|
||
|
|
|
||
|
|
if (valueList.length() != 3)
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a three elemental list, but got" +
|
||
|
|
valueList.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
NList nameNL = valueList.second();
|
||
|
|
NList typeNL = valueList.first();
|
||
|
|
NList dataNL = valueList.third();
|
||
|
|
|
||
|
|
// get distdata name
|
||
|
|
string name;
|
||
|
|
if (!nameNL.isString())
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a string atom as second list element, but got " +
|
||
|
|
nameNL.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
name = nameNL.str();
|
||
|
|
|
||
|
|
// get type constructor name
|
||
|
|
string type;
|
||
|
|
if (!typeNL.isString())
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a string atom as first list element, but got " +
|
||
|
|
typeNL.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
type = typeNL.str();
|
||
|
|
|
||
|
|
// get data string
|
||
|
|
string data;
|
||
|
|
if (!dataNL.isText())
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
ErrorReporter::ReportError(
|
||
|
|
"Excepted a text atom as third list element, but got " +
|
||
|
|
dataNL.convertToString());
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
data = dataNL.str();
|
||
|
|
|
||
|
|
// deconde data string
|
||
|
|
DistDataAttribute* ddAttr = new DistDataAttribute(0);
|
||
|
|
Base64 b64;
|
||
|
|
char bindata[b64.sizeDecoded(data.size())];
|
||
|
|
int size = b64.decode(data, bindata);
|
||
|
|
|
||
|
|
DistDataId id = DistDataReg::getId(type, name);
|
||
|
|
ddAttr->set(true, bindata, size, id);
|
||
|
|
|
||
|
|
correct = true;
|
||
|
|
|
||
|
|
return SetWord(ddAttr);
|
||
|
|
}
|
||
|
|
|
||
|
|
Word createDistData(const ListExpr type_Info)
|
||
|
|
{ return SetWord(new DistDataAttribute(0)); }
|
||
|
|
|
||
|
|
void DeleteDistData(const ListExpr type_Info, Word& w)
|
||
|
|
{
|
||
|
|
DistDataAttribute* ddAttr =
|
||
|
|
static_cast<DistDataAttribute*>(w.addr);
|
||
|
|
ddAttr->deleteFLOB();
|
||
|
|
delete ddAttr;
|
||
|
|
w.addr = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool OpenDistData(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word& value)
|
||
|
|
{
|
||
|
|
value = SetWord(Attribute::Open(valueRecord, offset, type_Info));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SaveDistData(
|
||
|
|
SmiRecord &valueRecord, size_t &offset,
|
||
|
|
const ListExpr type_Info, Word& value)
|
||
|
|
{
|
||
|
|
Attribute::Save(valueRecord, offset, type_Info,
|
||
|
|
static_cast<Attribute*>(value.addr));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CloseDistData(const ListExpr type_Info, Word& w)
|
||
|
|
{ delete(DistDataAttribute*)w.addr; }
|
||
|
|
|
||
|
|
Word CloneDistData(const ListExpr type_Info, const Word& w)
|
||
|
|
{
|
||
|
|
DistDataAttribute* src = static_cast<DistDataAttribute*>(w.addr);
|
||
|
|
DistDataAttribute* cpy = new DistDataAttribute(*src);
|
||
|
|
return SetWord(cpy);
|
||
|
|
}
|
||
|
|
|
||
|
|
void* CastDistData(void *addr)
|
||
|
|
{ return new(addr) DistDataAttribute; }
|
||
|
|
|
||
|
|
int SizeOfDistData()
|
||
|
|
{ return sizeof(DistDataAttribute); }
|
||
|
|
|
||
|
|
bool CheckDistData(ListExpr typeName, ListExpr &error_Info)
|
||
|
|
{ return (nl->IsEqual(typeName, DistDataAttribute::BasicType())); }
|
||
|
|
|
||
|
|
TypeConstructor distdata_tc(
|
||
|
|
DistDataAttribute::BasicType(), DistDataProp,
|
||
|
|
OutDistData, InDistData,
|
||
|
|
0, 0,
|
||
|
|
createDistData, DeleteDistData,
|
||
|
|
OpenDistData, SaveDistData,
|
||
|
|
CloseDistData, CloneDistData,
|
||
|
|
CastDistData, SizeOfDistData,
|
||
|
|
CheckDistData);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1. Operators
|
||
|
|
|
||
|
|
1.1.1 Value mappings
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
template <unsigned paramCnt> int
|
||
|
|
gethpoint_VM(
|
||
|
|
Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
HPointAttr* hpointAttr =
|
||
|
|
static_cast<HPointAttr*>(result.addr);
|
||
|
|
|
||
|
|
Attribute* attr = static_cast<Attribute*>(args[0].addr);
|
||
|
|
|
||
|
|
string typeName = static_cast<CcString*>(
|
||
|
|
args[paramCnt].addr)->GetValue();
|
||
|
|
|
||
|
|
string hpointName = static_cast<CcString*>(
|
||
|
|
args[paramCnt+1].addr)->GetValue();
|
||
|
|
|
||
|
|
HPointInfo info = HPointReg::getInfo(typeName, hpointName);
|
||
|
|
HPoint *p = info.getHPoint(attr);
|
||
|
|
hpointAttr->set(true, p);
|
||
|
|
delete p;
|
||
|
|
return 0;
|
||
|
|
} // gethpoint_VM
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned paramCnt> int
|
||
|
|
getbbox_VM(
|
||
|
|
Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
HRectAttr* hrectAttr =
|
||
|
|
static_cast<HRectAttr*>(result.addr);
|
||
|
|
|
||
|
|
Attribute* attr = static_cast<Attribute*>(args[0].addr);
|
||
|
|
|
||
|
|
string typeName = static_cast<CcString*>(
|
||
|
|
args[paramCnt].addr)->GetValue();
|
||
|
|
|
||
|
|
string hrectName = static_cast<CcString*>(
|
||
|
|
args[paramCnt+1].addr)->GetValue();
|
||
|
|
|
||
|
|
BBoxInfo info = BBoxReg::getInfo(typeName, hrectName);
|
||
|
|
HRect *r = info.getBBox(attr);
|
||
|
|
hrectAttr->set(true, r);
|
||
|
|
delete r;
|
||
|
|
return 0;
|
||
|
|
} // getbbox_VM
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned paramCnt> int
|
||
|
|
getdistdata_VM(
|
||
|
|
Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
DistDataAttribute* ddAttr =
|
||
|
|
static_cast<DistDataAttribute*>(result.addr);
|
||
|
|
|
||
|
|
Attribute* attr = static_cast<Attribute*>(args[0].addr);
|
||
|
|
|
||
|
|
string typeName = static_cast<CcString*>(
|
||
|
|
args[paramCnt].addr)->GetValue();
|
||
|
|
|
||
|
|
string dataName = static_cast<CcString*>(
|
||
|
|
args[paramCnt+1].addr)->GetValue();
|
||
|
|
|
||
|
|
DistDataId id = DistDataReg::getId(typeName, dataName);
|
||
|
|
DistDataInfo info = DistDataReg::getInfo(id);
|
||
|
|
DistData *ddata = info.getData(attr);
|
||
|
|
ddAttr->set(true, ddata, id);
|
||
|
|
delete ddata;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
} // getdistdata_VM
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned paramCnt> int
|
||
|
|
gdistance_VM(Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcReal* resultValue = static_cast<CcReal*>(result.addr);
|
||
|
|
|
||
|
|
Attribute* attr1 =
|
||
|
|
static_cast<Attribute*>(args[0].addr);
|
||
|
|
|
||
|
|
Attribute* attr2 =
|
||
|
|
static_cast<Attribute*>(args[1].addr);
|
||
|
|
|
||
|
|
string typeName =
|
||
|
|
static_cast<CcString*>(args[paramCnt].addr)->GetValue();
|
||
|
|
|
||
|
|
string distfunName =
|
||
|
|
static_cast<CcString*>(args[paramCnt+1].addr)->GetValue();
|
||
|
|
|
||
|
|
string dataName =
|
||
|
|
static_cast<CcString*>(args[paramCnt+2].addr)->GetValue();
|
||
|
|
|
||
|
|
double dist;
|
||
|
|
DistfunInfo df_info = DistfunReg::
|
||
|
|
getInfo(distfunName, typeName, dataName);
|
||
|
|
DistData *data1 = df_info.getData(attr1);
|
||
|
|
DistData *data2 = df_info.getData(attr2);
|
||
|
|
df_info.dist(data1, data2, dist);
|
||
|
|
delete data1;
|
||
|
|
delete data2;
|
||
|
|
resultValue->Set(true, dist);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
} // gdistance_VM
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned paramCnt> int
|
||
|
|
gdistanceDD_VM(Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s)
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcReal* resultValue = static_cast<CcReal*>(result.addr);
|
||
|
|
|
||
|
|
DistDataAttribute* ddAttr1 =
|
||
|
|
static_cast<DistDataAttribute*>(args[0].addr);
|
||
|
|
DistDataAttribute* ddAttr2 =
|
||
|
|
static_cast<DistDataAttribute*>(args[1].addr);
|
||
|
|
string distfunName =
|
||
|
|
static_cast<CcString*>(args[paramCnt].addr)->GetValue();
|
||
|
|
|
||
|
|
// check, if both attributes are assigned to the same
|
||
|
|
// attribute- and distdata-type
|
||
|
|
if (ddAttr1->distdataId() != ddAttr2->distdataId())
|
||
|
|
{
|
||
|
|
DistDataId id1 = ddAttr1->distdataId();
|
||
|
|
DistDataId id2 = ddAttr2->distdataId();
|
||
|
|
DistDataInfo info1 = DistDataReg::getInfo(id1);
|
||
|
|
DistDataInfo info2 = DistDataReg::getInfo(id2);
|
||
|
|
const string seperator = "\n" + string(70, '-') + "\n";
|
||
|
|
|
||
|
|
if ((id1.algebraId() != id2.algebraId()) ||
|
||
|
|
(id1.typeId() != id2.typeId()))
|
||
|
|
{ // type constructors not equal
|
||
|
|
cmsg.error() << seperator
|
||
|
|
<< "Operator gdistance got distdata attributes for \n"
|
||
|
|
<< "different attribute types: \""
|
||
|
|
<< info1.typeName() << "\", \"" << info2.typeName()
|
||
|
|
<< "\"!" << seperator << endl;
|
||
|
|
cmsg.send();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{ // distance functions not equal
|
||
|
|
cmsg.error() << seperator
|
||
|
|
<< "Operator gdistance got distdata attributes for \n"
|
||
|
|
<< "different data types \""
|
||
|
|
<< info1.name() << "\", \"" << info2.name()
|
||
|
|
<< "\"!" << seperator << endl;
|
||
|
|
cmsg.send();
|
||
|
|
}
|
||
|
|
resultValue->Set(false, 0);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// get distance function
|
||
|
|
DistfunInfo info = DistfunReg::getInfo(
|
||
|
|
distfunName, ddAttr1->distdataId());
|
||
|
|
|
||
|
|
// check, if selected distance function is defined
|
||
|
|
if(!info.isDefined())
|
||
|
|
{
|
||
|
|
DistDataInfo info = DistDataReg::
|
||
|
|
getInfo(ddAttr1->distdataId());
|
||
|
|
string typeName = info.typeName();
|
||
|
|
const string seperator = "\n" + string(70, '-') + "\n";
|
||
|
|
cmsg.error()
|
||
|
|
<< seperator
|
||
|
|
<< "Operator gdistance: \n"
|
||
|
|
<< "Distance function \"" << distfunName << "\" "
|
||
|
|
<< "for type \"" << typeName << "\" is not defined!" << endl
|
||
|
|
<< "Defined distance functions: " << endl << endl
|
||
|
|
<< DistfunReg::definedNames(typeName)
|
||
|
|
<< seperator << endl;
|
||
|
|
cmsg.send();
|
||
|
|
|
||
|
|
resultValue->Set(false, 0);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
double dist;
|
||
|
|
char * data = ddAttr1->getData();
|
||
|
|
DistData dd1(ddAttr1->size(), data);
|
||
|
|
delete [] data;
|
||
|
|
data = ddAttr2->getData();
|
||
|
|
DistData dd2(ddAttr2->size(),data);
|
||
|
|
delete[] data;
|
||
|
|
info.dist(&dd1, &dd2, dist);
|
||
|
|
resultValue->Set(true, dist);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
} // gdistanceDD_VM
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1.1 Type mappings
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
template<unsigned paramCnt>
|
||
|
|
ListExpr gethpoint_TM(ListExpr args)
|
||
|
|
{
|
||
|
|
if (!HPointReg::isInitialized())
|
||
|
|
HPointReg::initialize();
|
||
|
|
|
||
|
|
NList args_NL(args);
|
||
|
|
if(!args_NL.hasLength(paramCnt)){
|
||
|
|
stringstream err;
|
||
|
|
err << "Expected " << paramCnt << " arguments!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
|
||
|
|
NList data_NL = args_NL.first();
|
||
|
|
|
||
|
|
// CHECK_SYMBOL(data_NL, 1)
|
||
|
|
if(!data_NL.isSymbol()){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Argument 1 must be a symbol or an atomar type!");
|
||
|
|
}
|
||
|
|
|
||
|
|
string typeName = data_NL.str();
|
||
|
|
|
||
|
|
// select bbox type
|
||
|
|
string funName;
|
||
|
|
if (paramCnt == 2){
|
||
|
|
if(!args_NL.second().isSymbol()){
|
||
|
|
stringstream err;
|
||
|
|
err << "Argument 2 must be the name of an existing "
|
||
|
|
<< "gethpoint function or \"" + HPOINT_DEFAULT + "\"!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
funName = args_NL.second().str();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
funName = HPOINT_DEFAULT;
|
||
|
|
|
||
|
|
// check, if selected get-hpoint function is defined
|
||
|
|
if (funName == HPOINT_DEFAULT){
|
||
|
|
funName = HPointReg::defaultName(typeName);
|
||
|
|
if(funName == HPOINT_UNDEFINED){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "No default gethpoint function defined for type "
|
||
|
|
"constructor \"" + typeName + "\"!";
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
} else if(!HPointReg::isDefined(typeName, funName)){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "gethpoint function \"" + funName +
|
||
|
|
"\" for type constructor \"" + typeName +
|
||
|
|
"\" is not defined! Use \"" + HPOINT_DEFAULT +
|
||
|
|
"\" or one of the following names: \n\n" +
|
||
|
|
HPointReg::definedNames(typeName);
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
NList res1(Symbol::APPEND());
|
||
|
|
NList res2(NList(typeName, true), NList(funName, true));
|
||
|
|
NList res3(HPoint::BasicType());
|
||
|
|
NList result(res1, res2, res3);
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template<unsigned paramCnt>
|
||
|
|
ListExpr getbbox_TM(ListExpr args)
|
||
|
|
{
|
||
|
|
if (!BBoxReg::isInitialized()){
|
||
|
|
BBoxReg::initialize();
|
||
|
|
}
|
||
|
|
|
||
|
|
NList args_NL(args);
|
||
|
|
if(!args_NL.hasLength(paramCnt)){
|
||
|
|
stringstream err;
|
||
|
|
err << "Expected " << paramCnt << " arguments!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
|
||
|
|
NList data_NL = args_NL.first();
|
||
|
|
|
||
|
|
if(!data_NL.isSymbol()){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Argument 1 must be a symbol or an atomar type!");
|
||
|
|
}
|
||
|
|
|
||
|
|
string typeName = data_NL.str();
|
||
|
|
|
||
|
|
// select bbox type
|
||
|
|
string funName;
|
||
|
|
if (paramCnt == 2){
|
||
|
|
if(!args_NL.second().isSymbol()){
|
||
|
|
stringstream err;
|
||
|
|
err << "Argument 2 must be the name of an existing "
|
||
|
|
<< "gethrect function or \"" + BBOX_DEFAULT + "\"!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
funName = args_NL.second().str();
|
||
|
|
} else {
|
||
|
|
funName = BBOX_DEFAULT;
|
||
|
|
}
|
||
|
|
|
||
|
|
// check, if selected get-hrect function is defined
|
||
|
|
if (funName == BBOX_DEFAULT){
|
||
|
|
funName = BBoxReg::defaultName(typeName);
|
||
|
|
if(funName == BBOX_UNDEFINED){
|
||
|
|
string errmsg = "No default gethrect function defined for type "
|
||
|
|
"constructor \"" + typeName + "\"!";
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
} else if(!BBoxReg::isDefined(typeName, funName)){
|
||
|
|
string errmsg = "gethrect function \"" + funName +
|
||
|
|
"\" for type constructor \"" + typeName +
|
||
|
|
"\" is not defined! Use \"" + BBOX_DEFAULT +
|
||
|
|
"\" or one of the following names: \n\n" +
|
||
|
|
BBoxReg::definedNames(typeName);
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
NList res1(Symbol::APPEND());
|
||
|
|
NList res2(NList(typeName, true), NList(funName, true));
|
||
|
|
NList res3(HRect::BasicType());
|
||
|
|
NList result(res1, res2, res3);
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template<unsigned paramCnt>
|
||
|
|
ListExpr getdistdata_TM(ListExpr args)
|
||
|
|
{
|
||
|
|
#ifdef PRINT_DISTFUN_INFOS
|
||
|
|
if (!distfuninfos_shown)
|
||
|
|
{
|
||
|
|
distfuninfos_shown = true;
|
||
|
|
string distfun_str = DistfunReg::printDistfuns();
|
||
|
|
cmsg.info() << distfun_str;
|
||
|
|
cmsg.info() << "(this info is only shown once on the first "
|
||
|
|
<< "call of the getdistdata or gdistance "
|
||
|
|
<< "operator)" << endl;
|
||
|
|
cmsg.send();
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// initialize distance functions and distdata types
|
||
|
|
if (!DistfunReg::isInitialized())
|
||
|
|
DistfunReg::initialize();
|
||
|
|
|
||
|
|
NList args_NL(args);
|
||
|
|
if(!args_NL.hasLength(paramCnt)){
|
||
|
|
stringstream err;
|
||
|
|
err << "Expected " << paramCnt << " arguments!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
|
||
|
|
NList data_NL = args_NL.first();
|
||
|
|
if(!data_NL.isSymbol()){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Argument 1 must be a symbol or an atomar type!");
|
||
|
|
}
|
||
|
|
|
||
|
|
string typeName = data_NL.str();
|
||
|
|
|
||
|
|
// select distdata type
|
||
|
|
string dataName;
|
||
|
|
if (paramCnt == 2){
|
||
|
|
if(!args_NL.second().isSymbol()){
|
||
|
|
stringstream err;
|
||
|
|
err << "Argument 2 must be the name of an existing "
|
||
|
|
<< "distdata type or \"" + DDATA_DEFAULT + "\"!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
dataName = args_NL.second().str();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
dataName = DDATA_DEFAULT;
|
||
|
|
|
||
|
|
// check, if selected distdata type is defined
|
||
|
|
if (dataName == DDATA_DEFAULT){
|
||
|
|
dataName = DistDataReg::defaultName(typeName);
|
||
|
|
if(dataName == DDATA_UNDEFINED){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "No default distdata type defined for type "
|
||
|
|
"constructor \"" + typeName + "\"!";
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
} else if(!DistDataReg::isDefined(typeName, dataName)){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "Distdata type \"" + dataName + "\" for "
|
||
|
|
"type constructor \"" + typeName +
|
||
|
|
"\" is not defined! Defined names: \n\n" +
|
||
|
|
DistDataReg::definedNames(typeName);
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
NList res1(Symbol::APPEND());
|
||
|
|
NList res2(NList(typeName, true), NList(dataName, true));
|
||
|
|
NList res3(DistDataAttribute::BasicType());
|
||
|
|
NList result(res1, res2, res3);
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<unsigned paramCnt>
|
||
|
|
ListExpr gdistance_TM(ListExpr args)
|
||
|
|
{
|
||
|
|
#ifdef PRINT_DISTFUN_INFOS
|
||
|
|
if (!distfuninfos_shown)
|
||
|
|
{
|
||
|
|
distfuninfos_shown = true;
|
||
|
|
string distfun_str = DistfunReg::printDistfuns();
|
||
|
|
cmsg.info() << distfun_str;
|
||
|
|
cmsg.info() << "(this info is only shown once on the first "
|
||
|
|
<< "call of the getdistdata or gdistance "
|
||
|
|
<< "operator)" << endl;
|
||
|
|
cmsg.send();
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// initialize distance functions and distdata types
|
||
|
|
if (!DistfunReg::isInitialized())
|
||
|
|
DistfunReg::initialize();
|
||
|
|
|
||
|
|
NList args_NL(args);
|
||
|
|
|
||
|
|
if(!args_NL.hasLength(paramCnt)){
|
||
|
|
stringstream err;
|
||
|
|
err << "Expected " << paramCnt << " arguments!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
|
||
|
|
NList data1_NL = args_NL.first();
|
||
|
|
NList data2_NL = args_NL.second();
|
||
|
|
|
||
|
|
if(!data1_NL.isSymbol()){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Argument 1 must be a symbol or an atomar type!");
|
||
|
|
}
|
||
|
|
if(!data2_NL.isSymbol()){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Argument 2 must be a symbol or an atomar type!");
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!(data1_NL == data2_NL)){
|
||
|
|
return listutils::typeError(
|
||
|
|
"Expecting two data attributes of the same type!");
|
||
|
|
}
|
||
|
|
|
||
|
|
string typeName = data1_NL.str();
|
||
|
|
|
||
|
|
// select distfun name
|
||
|
|
string distfunName;
|
||
|
|
if (paramCnt >= 3){
|
||
|
|
if(!args_NL.third().isSymbol()){
|
||
|
|
stringstream err;
|
||
|
|
err << "Argument 3 must be the name of an existing "
|
||
|
|
<< "distance function or \"" + DFUN_DEFAULT + "\"!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
distfunName = args_NL.third().str();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
distfunName = DFUN_DEFAULT;
|
||
|
|
|
||
|
|
if(typeName == DistDataAttribute::BasicType())
|
||
|
|
{ // further type checkings for distdata attributes are done in
|
||
|
|
// the value mapping function, since they need the name of
|
||
|
|
// the assigned type constructor, which is stored within the
|
||
|
|
// attribute objects.
|
||
|
|
NList res1(Symbol::APPEND());
|
||
|
|
NList res2(distfunName, true); res2.enclose();
|
||
|
|
NList res3(CcReal::BasicType());
|
||
|
|
NList result(res1, res2, res3);
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
// select distdata type
|
||
|
|
string dataName;
|
||
|
|
if (paramCnt >= 4){
|
||
|
|
if(!args_NL.fourth().isSymbol()){
|
||
|
|
stringstream err;
|
||
|
|
err << "Argument 4 must be the name of an existing "
|
||
|
|
<< "distdata type or \"" + DDATA_DEFAULT + "\"!";
|
||
|
|
return listutils::typeError(err.str());
|
||
|
|
}
|
||
|
|
dataName = args_NL.fourth().str();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
dataName = DistDataReg::defaultName(typeName);
|
||
|
|
|
||
|
|
// check, if selected distdata type is defined
|
||
|
|
if (dataName == DDATA_DEFAULT){
|
||
|
|
dataName = DistDataReg::defaultName(typeName);
|
||
|
|
if(dataName == DDATA_UNDEFINED){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "No default distdata type defined for type "
|
||
|
|
"constructor \"" + typeName + "\"!";
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
} else if(!DistDataReg::isDefined(typeName, dataName)){
|
||
|
|
string errmsg;
|
||
|
|
errmsg = "Distdata type \"" + dataName + "\" for "
|
||
|
|
"type constructor \"" + typeName +
|
||
|
|
"\" is not defined! Defined names: \n\n" +
|
||
|
|
DistDataReg::definedNames(typeName);
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Returs a type error, if the specified distance function is not defined.
|
||
|
|
string errmsg;
|
||
|
|
if (distfunName == DFUN_DEFAULT){
|
||
|
|
distfunName = DistfunReg::defaultName(typeName);
|
||
|
|
if(distfunName == DFUN_UNDEFINED){
|
||
|
|
errmsg = "No default distance function defined for type \""
|
||
|
|
+ typeName + "\"!";
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (!DistfunReg::isDefined(distfunName, typeName, dataName)){
|
||
|
|
errmsg = "Distance function \"" + distfunName +
|
||
|
|
"\" not defined for type \"" +
|
||
|
|
typeName + "\" and data type \"" +
|
||
|
|
dataName + "\"! Defined names: \n\n" +
|
||
|
|
DistfunReg::definedNames(typeName);
|
||
|
|
return listutils::typeError(errmsg);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
NList res1(Symbol::APPEND());
|
||
|
|
NList res2(NList(
|
||
|
|
typeName, true),
|
||
|
|
NList(distfunName, true),
|
||
|
|
NList(dataName, true));
|
||
|
|
NList res3(CcReal::BasicType());
|
||
|
|
NList result(res1, res2, res3);
|
||
|
|
return result.listExpr();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1 Selection functions
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
int gdistance_Select(ListExpr args)
|
||
|
|
{
|
||
|
|
NList argsNL(args);
|
||
|
|
NList arg1 = argsNL.first();
|
||
|
|
|
||
|
|
if (arg1.isEqual(DistDataAttribute::BasicType()))
|
||
|
|
return 1;
|
||
|
|
else
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1 Value mapping arrays
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
ValueMapping gdistance_Map[] = {
|
||
|
|
gdistance_VM<2>,
|
||
|
|
gdistanceDD_VM<2>
|
||
|
|
};
|
||
|
|
|
||
|
|
ValueMapping gdistance2_Map[] = {
|
||
|
|
gdistance_VM<3>,
|
||
|
|
gdistanceDD_VM<3>
|
||
|
|
};
|
||
|
|
|
||
|
|
ValueMapping gdistance3_Map[] = {
|
||
|
|
gdistance_VM<4>,
|
||
|
|
gdistanceDD_VM<4>
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1.1 Operator Infos
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
struct gethpoint_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
gethpoint_Info()
|
||
|
|
{
|
||
|
|
name = "gethpoint";
|
||
|
|
signature = "DATA -> hpoint";
|
||
|
|
syntax = "gethpoint(_)";
|
||
|
|
meaning = "maps DATA to a hpoint, using the default "
|
||
|
|
"get-hpoint function";
|
||
|
|
example = "gethpoint(5)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct gethpoint2_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
gethpoint2_Info()
|
||
|
|
{
|
||
|
|
name = "gethpoint2";
|
||
|
|
signature = "DATA x symbol -> hpoint";
|
||
|
|
syntax = "gethpoint2(_, _)";
|
||
|
|
meaning = "maps DATA to a hpoint, using the get-hpoint "
|
||
|
|
"function specified in arg2";
|
||
|
|
example = "gethpoint2(5, native)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct getbbox_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
getbbox_Info()
|
||
|
|
{
|
||
|
|
name = "getbbox";
|
||
|
|
signature = "DATA -> hrect";
|
||
|
|
syntax = "getbbox(_)";
|
||
|
|
meaning = "maps DATA to a hpoint, using the default "
|
||
|
|
"get-hrect function";
|
||
|
|
example = "getbbox(5)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct getbbox2_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
getbbox2_Info()
|
||
|
|
{
|
||
|
|
name = "getbbox2";
|
||
|
|
signature = "DATA x symbol -> hrect";
|
||
|
|
syntax = "getbbox2(_, _)";
|
||
|
|
meaning = "maps DATA to a hpoint, using the get-hrect "
|
||
|
|
"function specified in arg2";
|
||
|
|
example = "getbbox2(5, native)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct getdistdata_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
getdistdata_Info()
|
||
|
|
{
|
||
|
|
name = "getdistdata";
|
||
|
|
signature = "DATA -> distdata";
|
||
|
|
syntax = "getdistdata(_)";
|
||
|
|
meaning = "maps DATA to a distdata attribute of the default "
|
||
|
|
"type for type constructor of DATA";
|
||
|
|
example = "getdistdata(5)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct getdistdata2_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
getdistdata2_Info()
|
||
|
|
{
|
||
|
|
name = "getdistdata2";
|
||
|
|
signature = "DATA x symbol -> distdata";
|
||
|
|
syntax = "getdistdata2(_, _)";
|
||
|
|
meaning = "maps DATA to a distdata attribute of the specified "
|
||
|
|
"distdata-type (arg2).";
|
||
|
|
example = "getdistdata2(5, native)";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct gdistance_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
gdistance_Info()
|
||
|
|
{
|
||
|
|
name = "gdistance";
|
||
|
|
signature = "DATA x DATA -> real";
|
||
|
|
syntax = "gdistance(_, _)";
|
||
|
|
meaning = "computes the distance between arg1 and arg2, "
|
||
|
|
"using the default distance function and default "
|
||
|
|
"distdata-type (distdata attributes use the "
|
||
|
|
"assigned distdata-type)";
|
||
|
|
example = "gdistance(5, 2)";
|
||
|
|
remark = "arg1 and arg2 must be of the same distdata-type";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct gdistance2_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
gdistance2_Info()
|
||
|
|
{
|
||
|
|
name = "gdistance2";
|
||
|
|
signature = "attribute x attribute x symbol -> real";
|
||
|
|
syntax = "gdistance2(_, _, _)";
|
||
|
|
meaning = "computes the distance between arg1 and arg2, "
|
||
|
|
"using the specified distance function (arg3) and "
|
||
|
|
"the default distdata-type (distdata attributes use "
|
||
|
|
"the assigned datatype)";
|
||
|
|
example = "gdistance2(5, 2, euclid)";
|
||
|
|
remark = "arg1 and arg2 must be of the same distdata-type, ";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
struct gdistance3_Info : OperatorInfo
|
||
|
|
{
|
||
|
|
gdistance3_Info()
|
||
|
|
{
|
||
|
|
name = "gdistance3";
|
||
|
|
signature = "attribute x attribute x symbol x symbol -> real";
|
||
|
|
syntax = "gdistance3(_, _, _, _)";
|
||
|
|
meaning = "computes the distance between arg1 and arg2, "
|
||
|
|
"using the specified distance function (arg3) and "
|
||
|
|
"the the specified distdata-type (arg4) ";
|
||
|
|
example = "gdistance3(5, 2, euclid, native)";
|
||
|
|
remark = "arg1 and arg2 must be of the same type, "
|
||
|
|
"no distdata attributes allowed";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/********************************************************************
|
||
|
|
1.1 Create and initialize the Algebra
|
||
|
|
|
||
|
|
********************************************************************/
|
||
|
|
class GeneralTreeAlgebra
|
||
|
|
: public Algebra
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
GeneralTreeAlgebra() : Algebra()
|
||
|
|
{
|
||
|
|
AddTypeConstructor(&hpoint_tc);
|
||
|
|
AddTypeConstructor(&hrect_tc);
|
||
|
|
AddTypeConstructor(&distdata_tc);
|
||
|
|
|
||
|
|
hpoint_tc.AssociateKind( Kind::DATA() );
|
||
|
|
hrect_tc.AssociateKind( Kind::DATA() );
|
||
|
|
distdata_tc.AssociateKind( Kind::DATA() );
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
gethpoint_Info(),
|
||
|
|
gethpoint_VM<1>,
|
||
|
|
gethpoint_TM<1>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
gethpoint2_Info(),
|
||
|
|
gethpoint_VM<2>,
|
||
|
|
gethpoint_TM<2>);
|
||
|
|
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
getbbox_Info(),
|
||
|
|
getbbox_VM<1>,
|
||
|
|
getbbox_TM<1>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
getbbox2_Info(),
|
||
|
|
getbbox_VM<2>,
|
||
|
|
getbbox_TM<2>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
getdistdata_Info(),
|
||
|
|
getdistdata_VM<1>,
|
||
|
|
getdistdata_TM<1>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
getdistdata2_Info(),
|
||
|
|
getdistdata_VM<2>,
|
||
|
|
getdistdata_TM<2>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
gdistance_Info(),
|
||
|
|
gdistance_Map,
|
||
|
|
gdistance_Select,
|
||
|
|
gdistance_TM<2>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
gdistance2_Info(),
|
||
|
|
gdistance2_Map,
|
||
|
|
gdistance_Select,
|
||
|
|
gdistance_TM<3>);
|
||
|
|
|
||
|
|
AddOperator(
|
||
|
|
gdistance3_Info(),
|
||
|
|
gdistance3_Map,
|
||
|
|
gdistance_Select,
|
||
|
|
gdistance_TM<4>);
|
||
|
|
}
|
||
|
|
|
||
|
|
~GeneralTreeAlgebra() {};
|
||
|
|
}; // class GeneralTreeAlgebra
|
||
|
|
|
||
|
|
} // namespace gta
|
||
|
|
|
||
|
|
|
||
|
|
extern "C"
|
||
|
|
Algebra* InitializeGeneralTreeAlgebra(
|
||
|
|
NestedList *nlRef, QueryProcessor *qpRef)
|
||
|
|
{
|
||
|
|
nl = nlRef;
|
||
|
|
qp = qpRef;
|
||
|
|
return (new gta::GeneralTreeAlgebra());
|
||
|
|
}
|