560 lines
14 KiB
C++
560 lines
14 KiB
C++
|
|
/*
|
|||
|
|
----
|
|||
|
|
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
|
|||
|
|
----
|
|||
|
|
|
|||
|
|
|
|||
|
|
[1] Implementation of the TrajectoryAnnotation Algebra
|
|||
|
|
|
|||
|
|
November, 2012. Katharina Rieder
|
|||
|
|
|
|||
|
|
|
|||
|
|
1 Overview
|
|||
|
|
|
|||
|
|
This implementation file essentially contains the implementation of the
|
|||
|
|
operation geocode.
|
|||
|
|
|
|||
|
|
2 Includes
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#include "Algebra.h"
|
|||
|
|
#include "NestedList.h"
|
|||
|
|
#include "ListUtils.h"
|
|||
|
|
#include "NList.h"
|
|||
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
|||
|
|
#include "QueryProcessor.h"
|
|||
|
|
#include "ConstructorTemplates.h"
|
|||
|
|
#include "StandardTypes.h"
|
|||
|
|
#include "StringUtils.h"
|
|||
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
|||
|
|
#include "Algebras/OSM/ShpFileReader.h"
|
|||
|
|
#include "Algebras/OSM/OsmImportOperator.h"
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <fstream>
|
|||
|
|
#include <stdexcept>
|
|||
|
|
#include <sstream>
|
|||
|
|
#include <string>
|
|||
|
|
#include <stdio.h>
|
|||
|
|
#include <stdlib.h>
|
|||
|
|
#include <sys/socket.h>
|
|||
|
|
#include <arpa/inet.h>
|
|||
|
|
#include <netdb.h>
|
|||
|
|
#include <errno.h>
|
|||
|
|
#include <math.h>
|
|||
|
|
#include <cmath>
|
|||
|
|
#include "TypeMapUtils.h"
|
|||
|
|
#include "Algebras/OSM/XmlFileReader.h"
|
|||
|
|
#include "Algebras/OSM/XmlParserInterface.h"
|
|||
|
|
#include <libxml/xmlmemory.h>
|
|||
|
|
#include <libxml/parser.h>
|
|||
|
|
|
|||
|
|
extern NestedList* nl;
|
|||
|
|
extern QueryProcessor *qp;
|
|||
|
|
|
|||
|
|
using namespace std;
|
|||
|
|
using namespace mappings;
|
|||
|
|
|
|||
|
|
//3 methodes for creation of the socket
|
|||
|
|
std::runtime_error CreateSocketError()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
std::ostringstream temp;
|
|||
|
|
|
|||
|
|
temp << "Socket-Fehler #" << errno << ": " << strerror(errno);
|
|||
|
|
|
|||
|
|
|
|||
|
|
return std::runtime_error(temp.str());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void SendAll(int socket, const char* const buf, const int size)
|
|||
|
|
{
|
|||
|
|
int bytesSent = 0; // amount of Bytes already send from the Buffer
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
int resulte = send(socket, buf + bytesSent, size - bytesSent, 0);
|
|||
|
|
if(resulte < 0) // If value < 0 throw an error
|
|||
|
|
{
|
|||
|
|
throw CreateSocketError();
|
|||
|
|
}
|
|||
|
|
bytesSent += resulte;
|
|||
|
|
} while(bytesSent < size);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void GetLine(int socket, std::stringstream& line)
|
|||
|
|
{
|
|||
|
|
for(char c; recv(socket, &c, 1, 0) > 0; line << c)
|
|||
|
|
{
|
|||
|
|
if(c == '\n')
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
throw CreateSocketError();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
void askGoogle(const string& street, const string& no,
|
|||
|
|
const string& postcode,const string& ci, Point& result) {
|
|||
|
|
//Check of spaces and special characters in URL
|
|||
|
|
string newSt = stringutils::replaceAll(street, " ", "%20");
|
|||
|
|
string newSt1 = stringutils::replaceAll(newSt, "<EFBFBD>", "ss");
|
|||
|
|
string newSt2 = stringutils::replaceAll(newSt1, "<EFBFBD>", "ae");
|
|||
|
|
string newSt3 = stringutils::replaceAll(newSt2, "<EFBFBD>", "oe");
|
|||
|
|
string newSt4 = stringutils::replaceAll(newSt3, "<EFBFBD>", "ue");
|
|||
|
|
string newSt5 = stringutils::replaceAll(newSt4, "<EFBFBD>", "Ae");
|
|||
|
|
string newSt6 = stringutils::replaceAll(newSt5, "<EFBFBD>", "Oe");
|
|||
|
|
string newSt7 = stringutils::replaceAll(newSt6, "<EFBFBD>", "Ue");
|
|||
|
|
|
|||
|
|
string newc = stringutils::replaceAll(ci, " ", "%20");
|
|||
|
|
string newc1 = stringutils::replaceAll(newc, "<EFBFBD>", "ss");
|
|||
|
|
string newc2 = stringutils::replaceAll(newc1, "<EFBFBD>", "ae");
|
|||
|
|
string newc3 = stringutils::replaceAll(newc2, "<EFBFBD>", "oe");
|
|||
|
|
string newc4 = stringutils::replaceAll(newc3, "<EFBFBD>", "ue");
|
|||
|
|
string newc5 = stringutils::replaceAll(newc4, "<EFBFBD>", "Ae");
|
|||
|
|
string newc6 = stringutils::replaceAll(newc5, "<EFBFBD>", "Oe");
|
|||
|
|
string newc7 = stringutils::replaceAll(newc6, "<EFBFBD>", "Ue");
|
|||
|
|
|
|||
|
|
string no1 = stringutils::replaceAll(no, " ", "%20");
|
|||
|
|
|
|||
|
|
|
|||
|
|
//constant values of url
|
|||
|
|
string pre="GET /maps/api/geocode/xml?address=";
|
|||
|
|
//string post="+CA&sensor=false HTTP/1.1\r\n;";
|
|||
|
|
//post +="Host: maps.googleapis.com\r\nConnection: close\r\n\r\n";
|
|||
|
|
//create url
|
|||
|
|
string request("");
|
|||
|
|
request += pre+ newSt7+ "+";
|
|||
|
|
request += no1+ "+" +postcode;
|
|||
|
|
request += "+" +newc7+"\n";
|
|||
|
|
|
|||
|
|
|
|||
|
|
usleep(120000); //wait because only 10 request per sec allowed
|
|||
|
|
|
|||
|
|
hostent* phe = gethostbyname("maps.googleapis.com");
|
|||
|
|
|
|||
|
|
//if host not found
|
|||
|
|
if(phe == NULL) {
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|||
|
|
//error while craeating socket
|
|||
|
|
if(Socket == -1) {
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sockaddr_in service;
|
|||
|
|
service.sin_family = AF_INET;
|
|||
|
|
service.sin_port = htons(80); // HTTP-Protocol use Port 80
|
|||
|
|
|
|||
|
|
char** p = phe->h_addr_list;
|
|||
|
|
int resulte;
|
|||
|
|
do {
|
|||
|
|
if(*p == NULL)
|
|||
|
|
{
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
service.sin_addr.s_addr = *reinterpret_cast<unsigned long*>(*p);
|
|||
|
|
++p;
|
|||
|
|
resulte = connect(Socket, reinterpret_cast<sockaddr*>(&service),
|
|||
|
|
sizeof(service));
|
|||
|
|
} while(resulte == -1);
|
|||
|
|
|
|||
|
|
|
|||
|
|
SendAll(Socket, request.c_str(), request.size());
|
|||
|
|
|
|||
|
|
// open output stream, delete old content
|
|||
|
|
ofstream fout("../bin/output.xml", ios::trunc);
|
|||
|
|
|
|||
|
|
if (fout.good()) {
|
|||
|
|
bool write = false;
|
|||
|
|
while(!fout.eof()) {
|
|||
|
|
stringstream line;
|
|||
|
|
try {
|
|||
|
|
GetLine(Socket, line);
|
|||
|
|
} catch(exception& e) {
|
|||
|
|
break; // Schleife verlassen
|
|||
|
|
}
|
|||
|
|
string l = stringutils::replaceAll(line.str(),"\r","");
|
|||
|
|
stringutils::trim(l);
|
|||
|
|
if(!write){
|
|||
|
|
write = stringutils::startsWith(l,"<?xml");
|
|||
|
|
}
|
|||
|
|
if (write) {
|
|||
|
|
fout << l << endl; // Zeile in die Datei schreiben.
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
//Close connection
|
|||
|
|
close(Socket);
|
|||
|
|
|
|||
|
|
// at this point google's answer is stored in file output.xml
|
|||
|
|
|
|||
|
|
//xml-Parser
|
|||
|
|
|
|||
|
|
xmlDocPtr doc;
|
|||
|
|
xmlNodePtr cur;
|
|||
|
|
xmlNodePtr subcur;
|
|||
|
|
xmlNodePtr subsubcur;
|
|||
|
|
xmlNodePtr subsubsubcur;
|
|||
|
|
doc = xmlParseFile("../bin/output.xml");
|
|||
|
|
cur = xmlDocGetRootElement(doc);
|
|||
|
|
|
|||
|
|
//check if Parentnode is available
|
|||
|
|
|
|||
|
|
if ( cur == NULL){ // document could not be parsed
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
cur = cur->children;
|
|||
|
|
double ausg1=0;
|
|||
|
|
double ausg2=0;
|
|||
|
|
bool f1 = false;
|
|||
|
|
bool f2 = false;
|
|||
|
|
|
|||
|
|
while (cur != NULL) {
|
|||
|
|
if ((xmlStrcmp(cur->name, (const xmlChar *)"result"))==0){
|
|||
|
|
subcur = cur->children;
|
|||
|
|
while (subcur != NULL) {
|
|||
|
|
if ((xmlStrcmp(subcur->name, (const xmlChar *)"geometry"))==0) {
|
|||
|
|
subsubcur = subcur->children;
|
|||
|
|
while (subsubcur != NULL) {
|
|||
|
|
if ((xmlStrcmp(subsubcur->name,(const xmlChar *)"location"))==0) {
|
|||
|
|
subsubsubcur = subsubcur->children;
|
|||
|
|
while (subsubsubcur != NULL) {
|
|||
|
|
if((xmlStrcmp(subsubsubcur->name,(const xmlChar *)"lat"))==0){
|
|||
|
|
xmlChar *val1;
|
|||
|
|
val1 =xmlNodeListGetString(doc,subsubsubcur->children,1);
|
|||
|
|
ausg1=OsmImportOperator::convStrToDbl((const char *)val1);
|
|||
|
|
f1 = true;
|
|||
|
|
xmlFree(val1);
|
|||
|
|
}
|
|||
|
|
if((xmlStrcmp(subsubsubcur->name,(const xmlChar *)"lng"))==0){
|
|||
|
|
xmlChar *val2;
|
|||
|
|
val2 = xmlNodeListGetString(doc, subsubsubcur->children,1);
|
|||
|
|
ausg2= OsmImportOperator::convStrToDbl((const char *)val2);
|
|||
|
|
f2 = true;
|
|||
|
|
xmlFree(val2);
|
|||
|
|
}
|
|||
|
|
subsubsubcur = subsubsubcur->next;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
subsubcur = subsubcur->next;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
subcur = subcur->next;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
cur = cur->next;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
xmlFreeDoc(doc);
|
|||
|
|
|
|||
|
|
if(f1 && f2){
|
|||
|
|
result.Set(ausg2, ausg1);
|
|||
|
|
} else {
|
|||
|
|
result.SetDefined(false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
4 Implementation of Algebra TrajectoryAnnotation in namespace tann
|
|||
|
|
|
|||
|
|
4.1 Implementation of operator geocode
|
|||
|
|
|
|||
|
|
Typemapping and Selection Funktion for geocode
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
namespace tann {
|
|||
|
|
|
|||
|
|
|
|||
|
|
ListExpr geocodeTM(ListExpr args){
|
|||
|
|
int len = nl->ListLength(args);
|
|||
|
|
string err = "(string x string x int x string) or "
|
|||
|
|
"(string x int x int x string) or (string x int x string) expected";
|
|||
|
|
if((len!=3) && (len !=4)){ // 3 oder 4 argumente
|
|||
|
|
return listutils::typeError(err);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(len == 3){
|
|||
|
|
if( !CcString::checkType(nl->First(args)) ||
|
|||
|
|
!CcInt::checkType(nl->Second(args)) ||
|
|||
|
|
!CcString::checkType(nl->Third(args))){
|
|||
|
|
return listutils::typeError(err);
|
|||
|
|
} else {
|
|||
|
|
return listutils::basicSymbol<Point>();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(len == 4){
|
|||
|
|
if( !CcString::checkType(nl->First(args)) ||
|
|||
|
|
(!CcString::checkType(nl->Second(args)) &&
|
|||
|
|
!CcInt::checkType(nl->Second(args))) ||
|
|||
|
|
!CcInt::checkType(nl->Third(args)) ||
|
|||
|
|
!CcString::checkType(nl->Fourth(args))){
|
|||
|
|
return listutils::typeError(err);
|
|||
|
|
} else {
|
|||
|
|
return listutils::basicSymbol<Point>();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
else {return listutils::typeError(err);}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int geocodeSelect(ListExpr args){
|
|||
|
|
int len = nl->ListLength(args);
|
|||
|
|
if(len == 3){ // string x int x string
|
|||
|
|
return 0; // index in umVM
|
|||
|
|
}
|
|||
|
|
if (len ==4) { // point x text x int
|
|||
|
|
if(CcString::checkType(nl->Second(args))) {
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
if (CcInt::checkType(nl->Second(args))){
|
|||
|
|
return 2;}
|
|||
|
|
else {
|
|||
|
|
return listutils::basicSymbol<Point>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return listutils::basicSymbol<Point>();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Map Value
|
|||
|
|
|
|||
|
|
//Liste aus drei Elementen
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
geocodeVM0 (Word* args, Word& result, int message,
|
|||
|
|
Word& local, Supplier s)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
CcString* st = (CcString*)args[0].addr;
|
|||
|
|
CcInt* plz = (CcInt*) args[1].addr;
|
|||
|
|
CcString* c = (CcString*) args[2].addr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
result = qp->ResultStorage(s);
|
|||
|
|
Point* res = (Point*) result.addr;
|
|||
|
|
//query processor has provided
|
|||
|
|
//a point instance for the result
|
|||
|
|
|
|||
|
|
|
|||
|
|
if(st->IsDefined() && plz->IsDefined() && c->IsDefined()){
|
|||
|
|
|
|||
|
|
string str=(string)(char*)(st)->GetStringval();
|
|||
|
|
int co = (plz)->GetIntval();
|
|||
|
|
string ci=(string)(char*)(c)->GetStringval();
|
|||
|
|
string postcode = stringutils::int2str(co);
|
|||
|
|
|
|||
|
|
//search for the beginning of the housenumber
|
|||
|
|
size_t pos = str.find_last_of("0123456789");
|
|||
|
|
string street;
|
|||
|
|
string no;
|
|||
|
|
|
|||
|
|
if(pos==string::npos){
|
|||
|
|
// Fehler: keine Ziffer enthalten
|
|||
|
|
res->SetDefined(false);
|
|||
|
|
return 0;
|
|||
|
|
} else {
|
|||
|
|
while((pos>0) && (str[pos]>='0') && (str[pos]<='9')){
|
|||
|
|
pos--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( (pos>0) || ((str[pos]>='0') && (str[pos]<='0'))){
|
|||
|
|
street = str.substr(0,pos+1);
|
|||
|
|
no = str.substr(pos+1);
|
|||
|
|
} else {
|
|||
|
|
res->SetDefined(false);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
askGoogle(street, no, postcode, ci, *res);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
else {
|
|||
|
|
res->SetDefined(false);
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//Liste aus vier Elementen
|
|||
|
|
int
|
|||
|
|
geocodeVM1 (Word* args, Word& result, int message,
|
|||
|
|
Word& local, Supplier s)
|
|||
|
|
{
|
|||
|
|
CcString* st = (CcString*)args[0].addr;
|
|||
|
|
CcString* no= (CcString*) args[1].addr;
|
|||
|
|
CcInt* plz = (CcInt*) args[2].addr;
|
|||
|
|
CcString* c = (CcString*) args[3].addr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
result = qp->ResultStorage(s);
|
|||
|
|
Point* res = (Point*) result.addr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
if(st->IsDefined() && no->IsDefined() && plz->IsDefined() && c->IsDefined()){
|
|||
|
|
|
|||
|
|
string street=(string)(char*)(st)->GetStringval();
|
|||
|
|
string number=(string)(char*)(no)->GetStringval();
|
|||
|
|
int co = (plz)->GetIntval();
|
|||
|
|
string ci=(string)(char*)(c)->GetStringval();
|
|||
|
|
string postcode = stringutils::int2str(co);
|
|||
|
|
|
|||
|
|
|
|||
|
|
askGoogle(street, number, postcode, ci, *res);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
else {
|
|||
|
|
res->SetDefined(false);
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
geocodeVM2 (Word* args, Word& result, int message,
|
|||
|
|
Word& local, Supplier s)
|
|||
|
|
{
|
|||
|
|
CcString* st = (CcString*)args[0].addr;
|
|||
|
|
CcInt* no= (CcInt*) args[1].addr;
|
|||
|
|
CcInt* plz = (CcInt*) args[2].addr;
|
|||
|
|
CcString* c = (CcString*) args[3].addr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
result = qp->ResultStorage(s);
|
|||
|
|
Point* res = (Point*) result.addr;
|
|||
|
|
|
|||
|
|
|
|||
|
|
if(st->IsDefined() && no->IsDefined() && plz->IsDefined() && c->IsDefined()){
|
|||
|
|
|
|||
|
|
string street=(string)(char*)(st)->GetStringval();
|
|||
|
|
int number=(no)->GetIntval();
|
|||
|
|
int co = (plz)->GetIntval();
|
|||
|
|
string ci=(string)(char*)(c)->GetStringval();
|
|||
|
|
string postcode = stringutils::int2str(co);
|
|||
|
|
string nr = stringutils::int2str(number);
|
|||
|
|
|
|||
|
|
askGoogle(street, nr, postcode, ci, *res);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
else {
|
|||
|
|
res->SetDefined(false);
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//5 Definition of operator geocode
|
|||
|
|
ValueMapping geocodeVM[] = {
|
|||
|
|
geocodeVM0,
|
|||
|
|
geocodeVM1,
|
|||
|
|
geocodeVM2
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
//Spezizikation
|
|||
|
|
const string geocodeSpec =
|
|||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
|||
|
|
"( <text>(string x int x string) -> point or "
|
|||
|
|
"(string x [string|int] x int x string) -> point</text--->"
|
|||
|
|
"<text>geocode(_,_,_,_)</text--->"
|
|||
|
|
"<text>Point to an address</text--->"
|
|||
|
|
"<text>query geocode('Universit<69>tsstr.', 11, 58097, 'Hagen')</text--->"
|
|||
|
|
") )";
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
Operator geocodeOp(
|
|||
|
|
"geocode", // Name des Operators
|
|||
|
|
geocodeSpec, // Spezifikation
|
|||
|
|
3, // Anzahl ValueMappings
|
|||
|
|
geocodeVM, // Array von ValueMappings
|
|||
|
|
geocodeSelect, // Selection Funktion
|
|||
|
|
geocodeTM // TypeMapping
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
5 Implementation of the Algebra Class
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
class TrajectoryAnnotationAlgebra : public Algebra
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
TrajectoryAnnotationAlgebra() : Algebra()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
5.1 Registration of Operators
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
AddOperator( &geocodeOp);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
~TrajectoryAnnotationAlgebra() {};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
} //end of namespace tann
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
6 Initialization
|
|||
|
|
|
|||
|
|
Each algebra module needs an initialization function. The algebra manager
|
|||
|
|
has a reference to this function if this algebra is included in the list
|
|||
|
|
of required algebras, thus forcing the linker to include this module.
|
|||
|
|
|
|||
|
|
The algebra manager invokes this function to get a reference to the instance
|
|||
|
|
of the algebra class and to provide references to the global nested list
|
|||
|
|
container (used to store constructor, type, operator and object information)
|
|||
|
|
and to the query processor.
|
|||
|
|
|
|||
|
|
The function has a C interface to make it possible to load the algebra
|
|||
|
|
dynamically at runtime.
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
extern "C"
|
|||
|
|
Algebra*
|
|||
|
|
InitializeTrajectoryAnnotationAlgebra( NestedList* nlRef,
|
|||
|
|
QueryProcessor* qpRef )
|
|||
|
|
{
|
|||
|
|
// The C++ scope-operator :: must be used to qualify the full name
|
|||
|
|
return new tann::TrajectoryAnnotationAlgebra;
|
|||
|
|
}
|