Implementation of turn restriction exceptions
This commit is contained in:
parent
5de2aa1cbf
commit
ffdaa71086
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
open source routing machine
|
open source routing machine
|
||||||
Copyright (C) Dennis Luxen, others 2010
|
Copyright (C) Dennis Luxen, others 2010
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU AFFERO General Public License as published by
|
it under the terms of the GNU AFFERO General Public License as published by
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
any later version.
|
any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@ -21,489 +21,524 @@
|
|||||||
#include "PBFParser.h"
|
#include "PBFParser.h"
|
||||||
|
|
||||||
PBFParser::PBFParser(const char * fileName) : externalMemory(NULL){
|
PBFParser::PBFParser(const char * fileName) : externalMemory(NULL){
|
||||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
|
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
|
||||||
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
|
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
|
||||||
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 ); /* Max 2500 items in queue, hardcoded. */
|
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 ); /* Max 2500 items in queue, hardcoded. */
|
||||||
input.open(fileName, std::ios::in | std::ios::binary);
|
input.open(fileName, std::ios::in | std::ios::binary);
|
||||||
|
|
||||||
if (!input) {
|
if (!input) {
|
||||||
std::cerr << fileName << ": File not found." << std::endl;
|
std::cerr << fileName << ": File not found." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
blockCount = 0;
|
blockCount = 0;
|
||||||
groupCount = 0;
|
groupCount = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PBFParser::RegisterCallbacks(ExtractorCallbacks * em) {
|
void PBFParser::RegisterCallbacks(ExtractorCallbacks * em) {
|
||||||
externalMemory = em;
|
externalMemory = em;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PBFParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
|
void PBFParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
|
||||||
scriptingEnvironment = _se;
|
scriptingEnvironment = _se;
|
||||||
|
|
||||||
|
if(lua_function_exists(scriptingEnvironment.getLuaStateForThreadID(0), "get_exceptions" )) {
|
||||||
|
//get list of turn restriction exceptions
|
||||||
|
try {
|
||||||
|
luabind::call_function<void>(
|
||||||
|
scriptingEnvironment.getLuaStateForThreadID(0),
|
||||||
|
"get_exceptions",
|
||||||
|
boost::ref(restriction_exceptions_vector)
|
||||||
|
);
|
||||||
|
INFO("Found " << restriction_exceptions_vector.size() << " exceptions to turn restriction");
|
||||||
|
BOOST_FOREACH(std::string & str, restriction_exceptions_vector) {
|
||||||
|
INFO("ignoring: " << str);
|
||||||
|
}
|
||||||
|
} catch (const luabind::error &er) {
|
||||||
|
lua_State* Ler=er.state();
|
||||||
|
report_errors(Ler, -1);
|
||||||
|
ERR(er.what());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
INFO("Found no exceptions to turn restrictions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PBFParser::~PBFParser() {
|
PBFParser::~PBFParser() {
|
||||||
if(input.is_open())
|
if(input.is_open())
|
||||||
input.close();
|
input.close();
|
||||||
|
|
||||||
// Clean up any leftover ThreadData objects in the queue
|
// Clean up any leftover ThreadData objects in the queue
|
||||||
_ThreadData* td;
|
_ThreadData* td;
|
||||||
while (threadDataQueue->try_pop(td)) {
|
while (threadDataQueue->try_pop(td)) {
|
||||||
delete td;
|
delete td;
|
||||||
}
|
}
|
||||||
google::protobuf::ShutdownProtobufLibrary();
|
google::protobuf::ShutdownProtobufLibrary();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups");
|
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::Init() {
|
inline bool PBFParser::Init() {
|
||||||
_ThreadData initData;
|
_ThreadData initData;
|
||||||
/** read Header */
|
/** read Header */
|
||||||
if(!readPBFBlobHeader(input, &initData)) {
|
if(!readPBFBlobHeader(input, &initData)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readBlob(input, &initData)) {
|
if(readBlob(input, &initData)) {
|
||||||
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
|
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
|
||||||
std::cerr << "[error] Header not parseable!" << std::endl;
|
std::cerr << "[error] Header not parseable!" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) {
|
for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) {
|
||||||
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
|
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
|
||||||
bool supported = false;
|
bool supported = false;
|
||||||
if ( "OsmSchema-V0.6" == feature )
|
if ( "OsmSchema-V0.6" == feature )
|
||||||
supported = true;
|
supported = true;
|
||||||
else if ( "DenseNodes" == feature )
|
else if ( "DenseNodes" == feature )
|
||||||
supported = true;
|
supported = true;
|
||||||
|
|
||||||
if ( !supported ) {
|
if ( !supported ) {
|
||||||
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
|
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "[error] blob not loaded!" << std::endl;
|
std::cerr << "[error] blob not loaded!" << std::endl;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::ReadData() {
|
inline void PBFParser::ReadData() {
|
||||||
bool keepRunning = true;
|
bool keepRunning = true;
|
||||||
do {
|
do {
|
||||||
_ThreadData *threadData = new _ThreadData();
|
_ThreadData *threadData = new _ThreadData();
|
||||||
keepRunning = readNextBlock(input, threadData);
|
keepRunning = readNextBlock(input, threadData);
|
||||||
|
|
||||||
if (keepRunning)
|
if (keepRunning)
|
||||||
threadDataQueue->push(threadData);
|
threadDataQueue->push(threadData);
|
||||||
else {
|
else {
|
||||||
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
|
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
|
||||||
delete threadData;
|
delete threadData;
|
||||||
}
|
}
|
||||||
} while(keepRunning);
|
} while(keepRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::ParseData() {
|
inline void PBFParser::ParseData() {
|
||||||
while (true) {
|
while (true) {
|
||||||
_ThreadData *threadData;
|
_ThreadData *threadData;
|
||||||
threadDataQueue->wait_and_pop(threadData);
|
threadDataQueue->wait_and_pop(threadData);
|
||||||
if (threadData == NULL) {
|
if (threadData == NULL) {
|
||||||
INFO("Parse Data Thread Finished");
|
INFO("Parse Data Thread Finished");
|
||||||
threadDataQueue->push(NULL); // Signal end of data for other threads
|
threadDataQueue->push(NULL); // Signal end of data for other threads
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBlock(threadData);
|
loadBlock(threadData);
|
||||||
|
|
||||||
for(int i = 0, groupSize = threadData->PBFprimitiveBlock.primitivegroup_size(); i < groupSize; ++i) {
|
for(int i = 0, groupSize = threadData->PBFprimitiveBlock.primitivegroup_size(); i < groupSize; ++i) {
|
||||||
threadData->currentGroupID = i;
|
threadData->currentGroupID = i;
|
||||||
loadGroup(threadData);
|
loadGroup(threadData);
|
||||||
|
|
||||||
if(threadData->entityTypeIndicator == TypeNode)
|
if(threadData->entityTypeIndicator == TypeNode)
|
||||||
parseNode(threadData);
|
parseNode(threadData);
|
||||||
if(threadData->entityTypeIndicator == TypeWay)
|
if(threadData->entityTypeIndicator == TypeWay)
|
||||||
parseWay(threadData);
|
parseWay(threadData);
|
||||||
if(threadData->entityTypeIndicator == TypeRelation)
|
if(threadData->entityTypeIndicator == TypeRelation)
|
||||||
parseRelation(threadData);
|
parseRelation(threadData);
|
||||||
if(threadData->entityTypeIndicator == TypeDenseNode)
|
if(threadData->entityTypeIndicator == TypeDenseNode)
|
||||||
parseDenseNode(threadData);
|
parseDenseNode(threadData);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete threadData;
|
delete threadData;
|
||||||
threadData = NULL;
|
threadData = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::Parse() {
|
inline bool PBFParser::Parse() {
|
||||||
// Start the read and parse threads
|
// Start the read and parse threads
|
||||||
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
|
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
|
||||||
|
|
||||||
//Open several parse threads that are synchronized before call to
|
//Open several parse threads that are synchronized before call to
|
||||||
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
|
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
|
||||||
|
|
||||||
// Wait for the threads to finish
|
// Wait for the threads to finish
|
||||||
readThread.join();
|
readThread.join();
|
||||||
parseThread.join();
|
parseThread.join();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
|
inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
|
||||||
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
|
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
|
||||||
int denseTagIndex = 0;
|
int denseTagIndex = 0;
|
||||||
int m_lastDenseID = 0;
|
int m_lastDenseID = 0;
|
||||||
int m_lastDenseLatitude = 0;
|
int m_lastDenseLatitude = 0;
|
||||||
int m_lastDenseLongitude = 0;
|
int m_lastDenseLongitude = 0;
|
||||||
|
|
||||||
ImportNode n;
|
ImportNode n;
|
||||||
std::vector<ImportNode> nodesToParse;
|
std::vector<ImportNode> nodesToParse;
|
||||||
for(int i = 0, idSize = dense.id_size(); i < idSize; ++i) {
|
for(int i = 0, idSize = dense.id_size(); i < idSize; ++i) {
|
||||||
n.Clear();
|
n.Clear();
|
||||||
m_lastDenseID += dense.id( i );
|
m_lastDenseID += dense.id( i );
|
||||||
m_lastDenseLatitude += dense.lat( i );
|
m_lastDenseLatitude += dense.lat( i );
|
||||||
m_lastDenseLongitude += dense.lon( i );
|
m_lastDenseLongitude += dense.lon( i );
|
||||||
n.id = m_lastDenseID;
|
n.id = m_lastDenseID;
|
||||||
n.lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() +threadData-> PBFprimitiveBlock.lat_offset() ) / NANO;
|
n.lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() +threadData-> PBFprimitiveBlock.lat_offset() ) / NANO;
|
||||||
n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
|
n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
|
||||||
while (denseTagIndex < dense.keys_vals_size()) {
|
while (denseTagIndex < dense.keys_vals_size()) {
|
||||||
const int tagValue = dense.keys_vals( denseTagIndex );
|
const int tagValue = dense.keys_vals( denseTagIndex );
|
||||||
if(tagValue == 0) {
|
if(tagValue == 0) {
|
||||||
++denseTagIndex;
|
++denseTagIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
|
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
|
||||||
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
|
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
|
||||||
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
|
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
|
||||||
n.keyVals.Add(key, value);
|
n.keyVals.Add(key, value);
|
||||||
denseTagIndex += 2;
|
denseTagIndex += 2;
|
||||||
}
|
}
|
||||||
nodesToParse.push_back(n);
|
nodesToParse.push_back(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned endi_nodes = nodesToParse.size();
|
unsigned endi_nodes = nodesToParse.size();
|
||||||
#pragma omp parallel for schedule ( guided )
|
#pragma omp parallel for schedule ( guided )
|
||||||
for(unsigned i = 0; i < endi_nodes; ++i) {
|
for(unsigned i = 0; i < endi_nodes; ++i) {
|
||||||
ImportNode &n = nodesToParse[i];
|
ImportNode &n = nodesToParse[i];
|
||||||
/** Pass the unpacked node to the LUA call back **/
|
/** Pass the unpacked node to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
luabind::call_function<int>(
|
luabind::call_function<int>(
|
||||||
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
|
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
|
||||||
"node_function",
|
"node_function",
|
||||||
boost::ref(n)
|
boost::ref(n)
|
||||||
);
|
);
|
||||||
} catch (const luabind::error &er) {
|
} catch (const luabind::error &er) {
|
||||||
lua_State* Ler=er.state();
|
lua_State* Ler=er.state();
|
||||||
report_errors(Ler, -1);
|
report_errors(Ler, -1);
|
||||||
ERR(er.what());
|
ERR(er.what());
|
||||||
}
|
}
|
||||||
// catch (...) {
|
// catch (...) {
|
||||||
// ERR("Unknown error occurred during PBF dense node parsing!");
|
// ERR("Unknown error occurred during PBF dense node parsing!");
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_FOREACH(ImportNode &n, nodesToParse) {
|
BOOST_FOREACH(ImportNode &n, nodesToParse) {
|
||||||
if(!externalMemory->nodeFunction(n))
|
if(!externalMemory->nodeFunction(n))
|
||||||
std::cerr << "[PBFParser] dense node not parsed" << std::endl;
|
std::cerr << "[PBFParser] dense node not parsed" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::parseNode(_ThreadData * ) {
|
inline void PBFParser::parseNode(_ThreadData * ) {
|
||||||
ERR("Parsing of simple nodes not supported. PBF should use dense nodes");
|
ERR("Parsing of simple nodes not supported. PBF should use dense nodes");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
||||||
//TODO: leave early, if relatio is not a restriction
|
//TODO: leave early, if relation is not a restriction
|
||||||
//TODO: reuse rawRestriction container
|
//TODO: reuse rawRestriction container
|
||||||
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
||||||
for(int i = 0; i < group.relations_size(); ++i ) {
|
for(int i = 0; i < group.relations_size(); ++i ) {
|
||||||
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
|
std::string exception_of_restriction_tag;
|
||||||
bool isRestriction = false;
|
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
|
||||||
bool isOnlyRestriction = false;
|
bool isRestriction = false;
|
||||||
for(int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) {
|
bool isOnlyRestriction = false;
|
||||||
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
|
for(int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) {
|
||||||
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
|
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
|
||||||
if ("type" == key) {
|
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
|
||||||
if( "restriction" == val)
|
if ("type" == key) {
|
||||||
isRestriction = true;
|
if( "restriction" == val)
|
||||||
else
|
isRestriction = true;
|
||||||
break;
|
else
|
||||||
}
|
break;
|
||||||
if ("restriction" == key) {
|
}
|
||||||
if(val.find("only_") == 0)
|
if ("restriction" == key) {
|
||||||
isOnlyRestriction = true;
|
if(val.find("only_") == 0)
|
||||||
}
|
isOnlyRestriction = true;
|
||||||
|
}
|
||||||
}
|
if ("except" == key) {
|
||||||
if(isRestriction) {
|
exception_of_restriction_tag = val;
|
||||||
long long lastRef = 0;
|
}
|
||||||
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
|
}
|
||||||
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
|
|
||||||
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
|
//Check if restriction shall be ignored
|
||||||
lastRef += inputRelation.memids(rolesIndex);
|
if(isRestriction && ("" != exception_of_restriction_tag) ) {
|
||||||
|
//Be warned, this is quadratic work here, but we assume that
|
||||||
if(false == ("from" == role || "to" == role || "via" == role)) {
|
//only a few exceptions are actually defined.
|
||||||
continue;
|
std::vector<std::string> tokenized_exception_tags_of_restriction;
|
||||||
}
|
boost::algorithm::split_regex(tokenized_exception_tags_of_restriction, exception_of_restriction_tag, boost::regex("[;][ ]*"));
|
||||||
|
BOOST_FOREACH(std::string & str, tokenized_exception_tags_of_restriction) {
|
||||||
switch(inputRelation.types(rolesIndex)) {
|
if(restriction_exceptions_vector.end() != std::find(restriction_exceptions_vector.begin(), restriction_exceptions_vector.end(), str)) {
|
||||||
case 0: //node
|
isRestriction = false;
|
||||||
if("from" == role || "to" == role) //Only via should be a node
|
break; //BOOST_FOREACH
|
||||||
continue;
|
}
|
||||||
assert("via" == role);
|
}
|
||||||
if(UINT_MAX != currentRestrictionContainer.viaNode)
|
}
|
||||||
currentRestrictionContainer.viaNode = UINT_MAX;
|
|
||||||
assert(UINT_MAX == currentRestrictionContainer.viaNode);
|
|
||||||
currentRestrictionContainer.restriction.viaNode = lastRef;
|
if(isRestriction) {
|
||||||
break;
|
long long lastRef = 0;
|
||||||
case 1: //way
|
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
|
||||||
assert("from" == role || "to" == role || "via" == role);
|
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
|
||||||
if("from" == role) {
|
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
|
||||||
currentRestrictionContainer.fromWay = lastRef;
|
lastRef += inputRelation.memids(rolesIndex);
|
||||||
}
|
|
||||||
if ("to" == role) {
|
if(!("from" == role || "to" == role || "via" == role)) {
|
||||||
currentRestrictionContainer.toWay = lastRef;
|
continue;
|
||||||
}
|
}
|
||||||
if ("via" == role) {
|
|
||||||
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
|
switch(inputRelation.types(rolesIndex)) {
|
||||||
currentRestrictionContainer.viaNode = lastRef;
|
case 0: //node
|
||||||
}
|
if("from" == role || "to" == role) //Only via should be a node
|
||||||
break;
|
continue;
|
||||||
case 2: //relation, not used. relations relating to relations are evil.
|
assert("via" == role);
|
||||||
continue;
|
if(UINT_MAX != currentRestrictionContainer.viaNode)
|
||||||
assert(false);
|
currentRestrictionContainer.viaNode = UINT_MAX;
|
||||||
break;
|
assert(UINT_MAX == currentRestrictionContainer.viaNode);
|
||||||
|
currentRestrictionContainer.restriction.viaNode = lastRef;
|
||||||
default: //should not happen
|
break;
|
||||||
//cout << "unknown";
|
case 1: //way
|
||||||
assert(false);
|
assert("from" == role || "to" == role || "via" == role);
|
||||||
break;
|
if("from" == role) {
|
||||||
}
|
currentRestrictionContainer.fromWay = lastRef;
|
||||||
}
|
}
|
||||||
// if(UINT_MAX != currentRestriction.viaNode) {
|
if ("to" == role) {
|
||||||
// cout << "restr from " << currentRestriction.from << " via ";
|
currentRestrictionContainer.toWay = lastRef;
|
||||||
// cout << "node " << currentRestriction.viaNode;
|
}
|
||||||
// cout << " to " << currentRestriction.to << endl;
|
if ("via" == role) {
|
||||||
// }
|
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
|
||||||
if(!externalMemory->restrictionFunction(currentRestrictionContainer))
|
currentRestrictionContainer.viaNode = lastRef;
|
||||||
std::cerr << "[PBFParser] relation not parsed" << std::endl;
|
}
|
||||||
}
|
break;
|
||||||
}
|
case 2: //relation, not used. relations relating to relations are evil.
|
||||||
|
continue;
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: //should not happen
|
||||||
|
//cout << "unknown";
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!externalMemory->restrictionFunction(currentRestrictionContainer))
|
||||||
|
std::cerr << "[PBFParser] relation not parsed" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::parseWay(_ThreadData * threadData) {
|
inline void PBFParser::parseWay(_ThreadData * threadData) {
|
||||||
_Way w;
|
_Way w;
|
||||||
std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
|
std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
|
||||||
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
|
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
|
||||||
w.Clear();
|
w.Clear();
|
||||||
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
||||||
w.id = inputWay.id();
|
w.id = inputWay.id();
|
||||||
unsigned pathNode(0);
|
unsigned pathNode(0);
|
||||||
for(int i = 0; i < inputWay.refs_size(); ++i) {
|
for(int i = 0; i < inputWay.refs_size(); ++i) {
|
||||||
pathNode += inputWay.refs(i);
|
pathNode += inputWay.refs(i);
|
||||||
w.path.push_back(pathNode);
|
w.path.push_back(pathNode);
|
||||||
}
|
}
|
||||||
assert(inputWay.keys_size() == inputWay.vals_size());
|
assert(inputWay.keys_size() == inputWay.vals_size());
|
||||||
for(int i = 0; i < inputWay.keys_size(); ++i) {
|
for(int i = 0; i < inputWay.keys_size(); ++i) {
|
||||||
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
|
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
|
||||||
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
|
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
|
||||||
w.keyVals.Add(key, val);
|
w.keyVals.Add(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
waysToParse.push_back(w);
|
waysToParse.push_back(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned endi_ways = waysToParse.size();
|
unsigned endi_ways = waysToParse.size();
|
||||||
#pragma omp parallel for schedule ( guided )
|
#pragma omp parallel for schedule ( guided )
|
||||||
for(unsigned i = 0; i < endi_ways; ++i) {
|
for(unsigned i = 0; i < endi_ways; ++i) {
|
||||||
_Way & w = waysToParse[i];
|
_Way & w = waysToParse[i];
|
||||||
/** Pass the unpacked way to the LUA call back **/
|
/** Pass the unpacked way to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
luabind::call_function<int>(
|
luabind::call_function<int>(
|
||||||
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
|
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
|
||||||
"way_function",
|
"way_function",
|
||||||
boost::ref(w),
|
boost::ref(w),
|
||||||
w.path.size()
|
w.path.size()
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (const luabind::error &er) {
|
} catch (const luabind::error &er) {
|
||||||
lua_State* Ler=er.state();
|
lua_State* Ler=er.state();
|
||||||
report_errors(Ler, -1);
|
report_errors(Ler, -1);
|
||||||
ERR(er.what());
|
ERR(er.what());
|
||||||
}
|
}
|
||||||
// catch (...) {
|
// catch (...) {
|
||||||
// ERR("Unknown error!");
|
// ERR("Unknown error!");
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(_Way & w, waysToParse) {
|
BOOST_FOREACH(_Way & w, waysToParse) {
|
||||||
if(!externalMemory->wayFunction(w)) {
|
if(!externalMemory->wayFunction(w)) {
|
||||||
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::loadGroup(_ThreadData * threadData) {
|
inline void PBFParser::loadGroup(_ThreadData * threadData) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
++groupCount;
|
++groupCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
||||||
threadData->entityTypeIndicator = 0;
|
threadData->entityTypeIndicator = 0;
|
||||||
if ( group.nodes_size() != 0 ) {
|
if ( group.nodes_size() != 0 ) {
|
||||||
threadData->entityTypeIndicator = TypeNode;
|
threadData->entityTypeIndicator = TypeNode;
|
||||||
}
|
}
|
||||||
if ( group.ways_size() != 0 ) {
|
if ( group.ways_size() != 0 ) {
|
||||||
threadData->entityTypeIndicator = TypeWay;
|
threadData->entityTypeIndicator = TypeWay;
|
||||||
}
|
}
|
||||||
if ( group.relations_size() != 0 ) {
|
if ( group.relations_size() != 0 ) {
|
||||||
threadData->entityTypeIndicator = TypeRelation;
|
threadData->entityTypeIndicator = TypeRelation;
|
||||||
}
|
}
|
||||||
if ( group.has_dense() ) {
|
if ( group.has_dense() ) {
|
||||||
threadData->entityTypeIndicator = TypeDenseNode;
|
threadData->entityTypeIndicator = TypeDenseNode;
|
||||||
assert( group.dense().id_size() != 0 );
|
assert( group.dense().id_size() != 0 );
|
||||||
}
|
}
|
||||||
assert( threadData->entityTypeIndicator != 0 );
|
assert( threadData->entityTypeIndicator != 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::loadBlock(_ThreadData * threadData) {
|
inline void PBFParser::loadBlock(_ThreadData * threadData) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
++blockCount;
|
++blockCount;
|
||||||
#endif
|
#endif
|
||||||
threadData->currentGroupID = 0;
|
threadData->currentGroupID = 0;
|
||||||
threadData->currentEntityID = 0;
|
threadData->currentEntityID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
|
inline bool PBFParser::readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
|
||||||
int size(0);
|
int size(0);
|
||||||
stream.read((char *)&size, sizeof(int));
|
stream.read((char *)&size, sizeof(int));
|
||||||
size = swapEndian(size);
|
size = swapEndian(size);
|
||||||
if(stream.eof()) {
|
if(stream.eof()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
|
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char *data = new char[size];
|
char *data = new char[size];
|
||||||
stream.read(data, size*sizeof(data[0]));
|
stream.read(data, size*sizeof(data[0]));
|
||||||
|
|
||||||
bool dataSuccessfullyParsed = (threadData->PBFBlobHeader).ParseFromArray( data, size);
|
bool dataSuccessfullyParsed = (threadData->PBFBlobHeader).ParseFromArray( data, size);
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return dataSuccessfullyParsed;
|
return dataSuccessfullyParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::unpackZLIB(std::fstream &, _ThreadData * threadData) {
|
inline bool PBFParser::unpackZLIB(std::fstream &, _ThreadData * threadData) {
|
||||||
unsigned rawSize = threadData->PBFBlob.raw_size();
|
unsigned rawSize = threadData->PBFBlob.raw_size();
|
||||||
char* unpackedDataArray = new char[rawSize];
|
char* unpackedDataArray = new char[rawSize];
|
||||||
z_stream compressedDataStream;
|
z_stream compressedDataStream;
|
||||||
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
|
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
|
||||||
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
|
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
|
||||||
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
|
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
|
||||||
compressedDataStream.avail_out = rawSize;
|
compressedDataStream.avail_out = rawSize;
|
||||||
compressedDataStream.zalloc = Z_NULL;
|
compressedDataStream.zalloc = Z_NULL;
|
||||||
compressedDataStream.zfree = Z_NULL;
|
compressedDataStream.zfree = Z_NULL;
|
||||||
compressedDataStream.opaque = Z_NULL;
|
compressedDataStream.opaque = Z_NULL;
|
||||||
int ret = inflateInit( &compressedDataStream );
|
int ret = inflateInit( &compressedDataStream );
|
||||||
if ( ret != Z_OK ) {
|
if ( ret != Z_OK ) {
|
||||||
std::cerr << "[error] failed to init zlib stream" << std::endl;
|
std::cerr << "[error] failed to init zlib stream" << std::endl;
|
||||||
delete[] unpackedDataArray;
|
delete[] unpackedDataArray;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = inflate( &compressedDataStream, Z_FINISH );
|
ret = inflate( &compressedDataStream, Z_FINISH );
|
||||||
if ( ret != Z_STREAM_END ) {
|
if ( ret != Z_STREAM_END ) {
|
||||||
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
|
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
|
||||||
std::cerr << "[error] Error type: " << ret << std::endl;
|
std::cerr << "[error] Error type: " << ret << std::endl;
|
||||||
delete[] unpackedDataArray;
|
delete[] unpackedDataArray;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = inflateEnd( &compressedDataStream );
|
ret = inflateEnd( &compressedDataStream );
|
||||||
if ( ret != Z_OK ) {
|
if ( ret != Z_OK ) {
|
||||||
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
|
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
|
||||||
delete[] unpackedDataArray;
|
delete[] unpackedDataArray;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
|
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
|
||||||
std::copy(unpackedDataArray, unpackedDataArray + rawSize, threadData->charBuffer.begin());
|
std::copy(unpackedDataArray, unpackedDataArray + rawSize, threadData->charBuffer.begin());
|
||||||
delete[] unpackedDataArray;
|
delete[] unpackedDataArray;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::unpackLZMA(std::fstream &, _ThreadData * ) {
|
inline bool PBFParser::unpackLZMA(std::fstream &, _ThreadData * ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PBFParser::readBlob(std::fstream& stream, _ThreadData * threadData) {
|
inline bool PBFParser::readBlob(std::fstream& stream, _ThreadData * threadData) {
|
||||||
if(stream.eof())
|
if(stream.eof())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int size = threadData->PBFBlobHeader.datasize();
|
const int size = threadData->PBFBlobHeader.datasize();
|
||||||
if ( size < 0 || size > MAX_BLOB_SIZE ) {
|
if ( size < 0 || size > MAX_BLOB_SIZE ) {
|
||||||
std::cerr << "[error] invalid Blob size:" << size << std::endl;
|
std::cerr << "[error] invalid Blob size:" << size << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* data = new char[size];
|
char* data = new char[size];
|
||||||
stream.read(data, sizeof(data[0])*size);
|
stream.read(data, sizeof(data[0])*size);
|
||||||
|
|
||||||
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
|
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
|
||||||
std::cerr << "[error] failed to parse blob" << std::endl;
|
std::cerr << "[error] failed to parse blob" << std::endl;
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( threadData->PBFBlob.has_raw() ) {
|
if ( threadData->PBFBlob.has_raw() ) {
|
||||||
const std::string& data = threadData->PBFBlob.raw();
|
const std::string& data = threadData->PBFBlob.raw();
|
||||||
threadData->charBuffer.clear();
|
threadData->charBuffer.clear();
|
||||||
threadData->charBuffer.resize( data.size() );
|
threadData->charBuffer.resize( data.size() );
|
||||||
std::copy(data.begin(), data.end(), threadData->charBuffer.begin());
|
std::copy(data.begin(), data.end(), threadData->charBuffer.begin());
|
||||||
} else if ( threadData->PBFBlob.has_zlib_data() ) {
|
} else if ( threadData->PBFBlob.has_zlib_data() ) {
|
||||||
if ( !unpackZLIB(stream, threadData) ) {
|
if ( !unpackZLIB(stream, threadData) ) {
|
||||||
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
|
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if ( threadData->PBFBlob.has_lzma_data() ) {
|
} else if ( threadData->PBFBlob.has_lzma_data() ) {
|
||||||
if ( !unpackLZMA(stream, threadData) )
|
if ( !unpackLZMA(stream, threadData) )
|
||||||
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
|
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "[error] Blob contains no data" << std::endl;
|
std::cerr << "[error] Blob contains no data" << std::endl;
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PBFParser::readNextBlock(std::fstream& stream, _ThreadData * threadData) {
|
bool PBFParser::readNextBlock(std::fstream& stream, _ThreadData * threadData) {
|
||||||
if(stream.eof()) {
|
if(stream.eof()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !readPBFBlobHeader(stream, threadData) ){
|
if ( !readPBFBlobHeader(stream, threadData) ){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
|
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !readBlob(stream, threadData) ) {
|
if ( !readBlob(stream, threadData) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
|
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
|
||||||
ERR("failed to parse PrimitiveBlock");
|
ERR("failed to parse PrimitiveBlock");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,8 @@ private:
|
|||||||
/* ThreadData Queue */
|
/* ThreadData Queue */
|
||||||
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
|
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
|
||||||
ScriptingEnvironment scriptingEnvironment;
|
ScriptingEnvironment scriptingEnvironment;
|
||||||
|
|
||||||
|
std::vector<std::string> restriction_exceptions_vector;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PBFPARSER_H_ */
|
#endif /* PBFPARSER_H_ */
|
||||||
|
@ -18,16 +18,7 @@
|
|||||||
or see http://www.gnu.org/licenses/agpl.txt.
|
or see http://www.gnu.org/licenses/agpl.txt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <lua.h>
|
|
||||||
#include <lauxlib.h>
|
|
||||||
#include <lualib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "ScriptingEnvironment.h"
|
#include "ScriptingEnvironment.h"
|
||||||
#include "../typedefs.h"
|
|
||||||
#include "../Util/LuaUtil.h"
|
|
||||||
#include "../Util/OpenMPWrapper.h"
|
|
||||||
|
|
||||||
ScriptingEnvironment::ScriptingEnvironment() {}
|
ScriptingEnvironment::ScriptingEnvironment() {}
|
||||||
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
||||||
@ -45,6 +36,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
|||||||
//open utility libraries string library;
|
//open utility libraries string library;
|
||||||
luaL_openlibs(myLuaState);
|
luaL_openlibs(myLuaState);
|
||||||
|
|
||||||
|
luaAddScriptFolderToLoadPath( myLuaState, fileName );
|
||||||
|
|
||||||
// Add our function to the state's global scope
|
// Add our function to the state's global scope
|
||||||
luabind::module(myLuaState) [
|
luabind::module(myLuaState) [
|
||||||
luabind::def("print", LUA_print<std::string>),
|
luabind::def("print", LUA_print<std::string>),
|
||||||
@ -53,17 +46,6 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
|||||||
luabind::def("parseDuration", parseDuration)
|
luabind::def("parseDuration", parseDuration)
|
||||||
];
|
];
|
||||||
|
|
||||||
luaAddScriptFolderToLoadPath( myLuaState, fileName );
|
|
||||||
|
|
||||||
//#pragma omp critical
|
|
||||||
// {
|
|
||||||
// if(0 != luaL_dostring(
|
|
||||||
// myLuaState,
|
|
||||||
// "print('Initializing LUA engine')\n"
|
|
||||||
// )) {
|
|
||||||
// ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
luabind::module(myLuaState) [
|
luabind::module(myLuaState) [
|
||||||
luabind::class_<HashTable<std::string, std::string> >("keyVals")
|
luabind::class_<HashTable<std::string, std::string> >("keyVals")
|
||||||
.def("Add", &HashTable<std::string, std::string>::Add)
|
.def("Add", &HashTable<std::string, std::string>::Add)
|
||||||
@ -96,13 +78,17 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
|||||||
.def_readwrite("tags", &_Way::keyVals)
|
.def_readwrite("tags", &_Way::keyVals)
|
||||||
.def_readwrite("direction", &_Way::direction)
|
.def_readwrite("direction", &_Way::direction)
|
||||||
.enum_("constants")
|
.enum_("constants")
|
||||||
[
|
[
|
||||||
luabind::value("notSure", 0),
|
luabind::value("notSure", 0),
|
||||||
luabind::value("oneway", 1),
|
luabind::value("oneway", 1),
|
||||||
luabind::value("bidirectional", 2),
|
luabind::value("bidirectional", 2),
|
||||||
luabind::value("opposite", 3)
|
luabind::value("opposite", 3)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
luabind::module(myLuaState) [
|
||||||
|
luabind::class_<std::vector<std::string> >("vector")
|
||||||
|
.def("Add", &std::vector<std::string>::push_back)
|
||||||
|
];
|
||||||
|
|
||||||
// Now call our function in a lua script
|
// Now call our function in a lua script
|
||||||
//#pragma omp critical
|
//#pragma omp critical
|
||||||
|
@ -31,7 +31,10 @@ extern "C" {
|
|||||||
#include "ExtractionHelperFunctions.h"
|
#include "ExtractionHelperFunctions.h"
|
||||||
#include "ExtractorStructs.h"
|
#include "ExtractorStructs.h"
|
||||||
|
|
||||||
|
#include "../typedefs.h"
|
||||||
#include "../DataStructures/ImportNode.h"
|
#include "../DataStructures/ImportNode.h"
|
||||||
|
#include "../Util/LuaUtil.h"
|
||||||
|
#include "../Util/OpenMPWrapper.h"
|
||||||
|
|
||||||
class ScriptingEnvironment {
|
class ScriptingEnvironment {
|
||||||
public:
|
public:
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
open source routing machine
|
open source routing machine
|
||||||
Copyright (C) Dennis Luxen, others 2010
|
Copyright (C) Dennis Luxen, others 2010
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU AFFERO General Public License as published by
|
it under the terms of the GNU AFFERO General Public License as published by
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
any later version.
|
any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@ -28,263 +28,304 @@
|
|||||||
|
|
||||||
|
|
||||||
XMLParser::XMLParser(const char * filename) : externalMemory(NULL), myLuaState(NULL){
|
XMLParser::XMLParser(const char * filename) : externalMemory(NULL), myLuaState(NULL){
|
||||||
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
|
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
|
||||||
inputReader = inputReaderFactory(filename);
|
inputReader = inputReaderFactory(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLParser::~XMLParser() {}
|
XMLParser::~XMLParser() {}
|
||||||
|
|
||||||
void XMLParser::RegisterCallbacks(ExtractorCallbacks * em) {
|
void XMLParser::RegisterCallbacks(ExtractorCallbacks * em) {
|
||||||
externalMemory = em;
|
externalMemory = em;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
|
void XMLParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
|
||||||
myLuaState = _se.getLuaStateForThreadID(0);
|
myLuaState = _se.getLuaStateForThreadID(0);
|
||||||
|
if(lua_function_exists(myLuaState, "get_exceptions" )) {
|
||||||
|
//get list of turn restriction exceptions
|
||||||
|
try {
|
||||||
|
luabind::call_function<void>(
|
||||||
|
myLuaState,
|
||||||
|
"get_exceptions",
|
||||||
|
boost::ref(restriction_exceptions_vector)
|
||||||
|
);
|
||||||
|
INFO("Found " << restriction_exceptions_vector.size() << " exceptions to turn restriction");
|
||||||
|
BOOST_FOREACH(std::string & str, restriction_exceptions_vector) {
|
||||||
|
INFO(" " << str);
|
||||||
|
}
|
||||||
|
} catch (const luabind::error &er) {
|
||||||
|
lua_State* Ler=er.state();
|
||||||
|
report_errors(Ler, -1);
|
||||||
|
ERR(er.what());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
INFO("Found no exceptions to turn restrictions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLParser::Init() {
|
bool XMLParser::Init() {
|
||||||
return (xmlTextReaderRead( inputReader ) == 1);
|
return (xmlTextReaderRead( inputReader ) == 1);
|
||||||
}
|
}
|
||||||
bool XMLParser::Parse() {
|
bool XMLParser::Parse() {
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||||
const int type = xmlTextReaderNodeType( inputReader );
|
const int type = xmlTextReaderNodeType( inputReader );
|
||||||
|
|
||||||
//1 is Element
|
//1 is Element
|
||||||
if ( type != 1 )
|
if ( type != 1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xmlChar* currentName = xmlTextReaderName( inputReader );
|
xmlChar* currentName = xmlTextReaderName( inputReader );
|
||||||
if ( currentName == NULL )
|
if ( currentName == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
|
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
|
||||||
ImportNode n = _ReadXMLNode( );
|
ImportNode n = _ReadXMLNode( );
|
||||||
/** Pass the unpacked node to the LUA call back **/
|
/** Pass the unpacked node to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
luabind::call_function<int>(
|
luabind::call_function<int>(
|
||||||
myLuaState,
|
myLuaState,
|
||||||
"node_function",
|
"node_function",
|
||||||
boost::ref(n)
|
boost::ref(n)
|
||||||
);
|
);
|
||||||
if(!externalMemory->nodeFunction(n))
|
if(!externalMemory->nodeFunction(n))
|
||||||
std::cerr << "[XMLParser] dense node not parsed" << std::endl;
|
std::cerr << "[XMLParser] dense node not parsed" << std::endl;
|
||||||
} catch (const luabind::error &er) {
|
} catch (const luabind::error &er) {
|
||||||
std::cerr << er.what() << std::endl;
|
std::cerr << er.what() << std::endl;
|
||||||
lua_State* Ler=er.state();
|
lua_State* Ler=er.state();
|
||||||
report_errors(Ler, -1);
|
report_errors(Ler, -1);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
ERR(e.what());
|
ERR(e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ERR("Unknown error occurred during XML node parsing!");
|
ERR("Unknown error occurred during XML node parsing!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
|
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
|
||||||
_Way way = _ReadXMLWay( );
|
_Way way = _ReadXMLWay( );
|
||||||
|
|
||||||
/** Pass the unpacked way to the LUA call back **/
|
/** Pass the unpacked way to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
luabind::call_function<int>(
|
luabind::call_function<int>(
|
||||||
myLuaState,
|
myLuaState,
|
||||||
"way_function",
|
"way_function",
|
||||||
boost::ref(way),
|
boost::ref(way),
|
||||||
way.path.size()
|
way.path.size()
|
||||||
);
|
);
|
||||||
if(!externalMemory->wayFunction(way)) {
|
if(!externalMemory->wayFunction(way)) {
|
||||||
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
||||||
}
|
}
|
||||||
} catch (const luabind::error &er) {
|
} catch (const luabind::error &er) {
|
||||||
std::cerr << er.what() << std::endl;
|
std::cerr << er.what() << std::endl;
|
||||||
lua_State* Ler=er.state();
|
lua_State* Ler=er.state();
|
||||||
report_errors(Ler, -1);
|
report_errors(Ler, -1);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
ERR(e.what());
|
ERR(e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ERR("Unknown error occurred during XML way parsing!");
|
ERR("Unknown error occurred during XML way parsing!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
|
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
|
||||||
_RawRestrictionContainer r = _ReadXMLRestriction();
|
_RawRestrictionContainer r = _ReadXMLRestriction();
|
||||||
if(r.fromWay != UINT_MAX) {
|
if(r.fromWay != UINT_MAX) {
|
||||||
if(!externalMemory->restrictionFunction(r)) {
|
if(!externalMemory->restrictionFunction(r)) {
|
||||||
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
|
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xmlFree( currentName );
|
xmlFree( currentName );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
|
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
|
||||||
_RawRestrictionContainer restriction;
|
_RawRestrictionContainer restriction;
|
||||||
|
std::string exception_of_restriction_tag;
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
bool restriction_is_excepted = false;
|
||||||
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
||||||
if ( childType != 1 && childType != 15 )
|
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||||
continue;
|
const int childType = xmlTextReaderNodeType( inputReader );
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
if ( childType != 1 && childType != 15 )
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
continue;
|
||||||
if ( childName == NULL )
|
const int childDepth = xmlTextReaderDepth( inputReader );
|
||||||
continue;
|
xmlChar* childName = xmlTextReaderName( inputReader );
|
||||||
|
if ( childName == NULL )
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) {
|
continue;
|
||||||
xmlFree( childName );
|
|
||||||
break;
|
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) {
|
||||||
}
|
xmlFree( childName );
|
||||||
if ( childType != 1 ) {
|
break;
|
||||||
xmlFree( childName );
|
}
|
||||||
continue;
|
if ( childType != 1 ) {
|
||||||
}
|
xmlFree( childName );
|
||||||
|
continue;
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
}
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
||||||
if ( k != NULL && value != NULL ) {
|
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
||||||
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){
|
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
||||||
if(0 == std::string((const char *) value).find("only_"))
|
if ( k != NULL && value != NULL ) {
|
||||||
restriction.restriction.flags.isOnly = true;
|
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){
|
||||||
}
|
if(0 == std::string((const char *) value).find("only_"))
|
||||||
|
restriction.restriction.flags.isOnly = true;
|
||||||
}
|
}
|
||||||
if ( k != NULL )
|
}
|
||||||
xmlFree( k );
|
if ( xmlStrEqual(k, (const xmlChar *) "except") ) {
|
||||||
if ( value != NULL )
|
exception_of_restriction_tag = (const char*) value;
|
||||||
xmlFree( value );
|
}
|
||||||
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) {
|
|
||||||
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
if ( k != NULL )
|
||||||
if ( ref != NULL ) {
|
xmlFree( k );
|
||||||
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
|
if ( value != NULL )
|
||||||
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
|
xmlFree( value );
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) {
|
||||||
restriction.toWay = atoi((const char*) ref);
|
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
||||||
}
|
if ( ref != NULL ) {
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
|
||||||
restriction.fromWay = atoi((const char*) ref);
|
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
|
||||||
}
|
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
|
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
||||||
restriction.restriction.viaNode = atoi((const char*) ref);
|
restriction.toWay = atoi((const char*) ref);
|
||||||
}
|
}
|
||||||
|
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
||||||
if(NULL != type)
|
restriction.fromWay = atoi((const char*) ref);
|
||||||
xmlFree( type );
|
}
|
||||||
if(NULL != role)
|
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
|
||||||
xmlFree( role );
|
restriction.restriction.viaNode = atoi((const char*) ref);
|
||||||
if(NULL != ref)
|
}
|
||||||
xmlFree( ref );
|
|
||||||
}
|
if(NULL != type)
|
||||||
}
|
xmlFree( type );
|
||||||
xmlFree( childName );
|
if(NULL != role)
|
||||||
}
|
xmlFree( role );
|
||||||
}
|
if(NULL != ref)
|
||||||
return restriction;
|
xmlFree( ref );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlFree( childName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if restriction shall be ignored
|
||||||
|
if( "" != exception_of_restriction_tag ) {
|
||||||
|
//Be warned, this is quadratic work here, but we assume that
|
||||||
|
//only a few exceptions are actually defined.
|
||||||
|
std::vector<std::string> tokenized_exception_tags_of_restriction;
|
||||||
|
boost::algorithm::split_regex(tokenized_exception_tags_of_restriction, exception_of_restriction_tag, boost::regex("[;][ ]*"));
|
||||||
|
BOOST_FOREACH(std::string & str, tokenized_exception_tags_of_restriction) {
|
||||||
|
if(restriction_exceptions_vector.end() != std::find(restriction_exceptions_vector.begin(), restriction_exceptions_vector.end(), str)) {
|
||||||
|
restriction.fromWay = UINT_MAX; //workaround to ignore the restriction
|
||||||
|
break; //BOOST_FOREACH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Way XMLParser::_ReadXMLWay() {
|
_Way XMLParser::_ReadXMLWay() {
|
||||||
_Way way;
|
_Way way;
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
||||||
const int depth = xmlTextReaderDepth( inputReader );
|
const int depth = xmlTextReaderDepth( inputReader );
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
const int childType = xmlTextReaderNodeType( inputReader );
|
||||||
if ( childType != 1 && childType != 15 )
|
if ( childType != 1 && childType != 15 )
|
||||||
continue;
|
continue;
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
const int childDepth = xmlTextReaderDepth( inputReader );
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
xmlChar* childName = xmlTextReaderName( inputReader );
|
||||||
if ( childName == NULL )
|
if ( childName == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
|
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
|
||||||
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
||||||
way.id = atoi((char*)id);
|
way.id = atoi((char*)id);
|
||||||
xmlFree(id);
|
xmlFree(id);
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( childType != 1 ) {
|
if ( childType != 1 ) {
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
||||||
// cout << "->k=" << k << ", v=" << value << endl;
|
// cout << "->k=" << k << ", v=" << value << endl;
|
||||||
if ( k != NULL && value != NULL ) {
|
if ( k != NULL && value != NULL ) {
|
||||||
|
|
||||||
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
|
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
|
||||||
}
|
}
|
||||||
if ( k != NULL )
|
if ( k != NULL )
|
||||||
xmlFree( k );
|
xmlFree( k );
|
||||||
if ( value != NULL )
|
if ( value != NULL )
|
||||||
xmlFree( value );
|
xmlFree( value );
|
||||||
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
|
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
|
||||||
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
||||||
if ( ref != NULL ) {
|
if ( ref != NULL ) {
|
||||||
way.path.push_back( atoi(( const char* ) ref ) );
|
way.path.push_back( atoi(( const char* ) ref ) );
|
||||||
xmlFree( ref );
|
xmlFree( ref );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return way;
|
return way;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportNode XMLParser::_ReadXMLNode() {
|
ImportNode XMLParser::_ReadXMLNode() {
|
||||||
ImportNode node;
|
ImportNode node;
|
||||||
|
|
||||||
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
|
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
|
||||||
if ( attribute != NULL ) {
|
if ( attribute != NULL ) {
|
||||||
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
|
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
|
||||||
xmlFree( attribute );
|
xmlFree( attribute );
|
||||||
}
|
}
|
||||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
|
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
|
||||||
if ( attribute != NULL ) {
|
if ( attribute != NULL ) {
|
||||||
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
|
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
|
||||||
xmlFree( attribute );
|
xmlFree( attribute );
|
||||||
}
|
}
|
||||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
||||||
if ( attribute != NULL ) {
|
if ( attribute != NULL ) {
|
||||||
node.id = atoi(( const char* ) attribute );
|
node.id = atoi(( const char* ) attribute );
|
||||||
xmlFree( attribute );
|
xmlFree( attribute );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
||||||
const int depth = xmlTextReaderDepth( inputReader );
|
const int depth = xmlTextReaderDepth( inputReader );
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
const int childType = xmlTextReaderNodeType( inputReader );
|
||||||
// 1 = Element, 15 = EndElement
|
// 1 = Element, 15 = EndElement
|
||||||
if ( childType != 1 && childType != 15 )
|
if ( childType != 1 && childType != 15 )
|
||||||
continue;
|
continue;
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
const int childDepth = xmlTextReaderDepth( inputReader );
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
xmlChar* childName = xmlTextReaderName( inputReader );
|
||||||
if ( childName == NULL )
|
if ( childName == NULL )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
|
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( childType != 1 ) {
|
if ( childType != 1 ) {
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
||||||
if ( k != NULL && value != NULL ) {
|
if ( k != NULL && value != NULL ) {
|
||||||
node.keyVals.Add(std::string( reinterpret_cast<char*>(k) ), std::string( reinterpret_cast<char*>(value)));
|
node.keyVals.Add(std::string( reinterpret_cast<char*>(k) ), std::string( reinterpret_cast<char*>(value)));
|
||||||
}
|
}
|
||||||
if ( k != NULL )
|
if ( k != NULL )
|
||||||
xmlFree( k );
|
xmlFree( k );
|
||||||
if ( value != NULL )
|
if ( value != NULL )
|
||||||
xmlFree( value );
|
xmlFree( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFree( childName );
|
xmlFree( childName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ private:
|
|||||||
xmlTextReaderPtr inputReader;
|
xmlTextReaderPtr inputReader;
|
||||||
ExtractorCallbacks * externalMemory;
|
ExtractorCallbacks * externalMemory;
|
||||||
lua_State *myLuaState;
|
lua_State *myLuaState;
|
||||||
|
|
||||||
|
std::vector<std::string> restriction_exceptions_vector;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* XMLPARSER_H_ */
|
#endif /* XMLPARSER_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user