void LoadNodeAndEdgeInformation(const boost::filesystem::path &nodes_file,
                                    const boost::filesystem::path &edges_file)
    {
        boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);

        QueryNode current_node;
        unsigned number_of_coordinates = 0;
        nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
        m_coordinate_list =
            std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
        for (unsigned i = 0; i < number_of_coordinates; ++i)
        {
            nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
            m_coordinate_list->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
            BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lat) >> 30) == 0);
            BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lon) >> 30) == 0);
        }
        nodes_input_stream.close();

        boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
        unsigned number_of_edges = 0;
        edges_input_stream.read((char *)&number_of_edges, sizeof(unsigned));
        m_via_node_list.resize(number_of_edges);
        m_name_ID_list.resize(number_of_edges);
        m_turn_instruction_list.resize(number_of_edges);
        m_travel_mode_list.resize(number_of_edges);
        m_edge_is_compressed.resize(number_of_edges);

        unsigned compressed = 0;

        OriginalEdgeData current_edge_data;
        for (unsigned i = 0; i < number_of_edges; ++i)
        {
            edges_input_stream.read((char *)&(current_edge_data), sizeof(OriginalEdgeData));
            m_via_node_list[i] = current_edge_data.via_node;
            m_name_ID_list[i] = current_edge_data.name_id;
            m_turn_instruction_list[i] = current_edge_data.turn_instruction;
            m_travel_mode_list[i] = current_edge_data.travel_mode;
            m_edge_is_compressed[i] = current_edge_data.compressed_geometry;
            if (m_edge_is_compressed[i])
            {
                ++compressed;
            }
        }

        edges_input_stream.close();
    }
Пример #2
0
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
    boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);

    QueryNode current_node;
    unsigned coordinate_count = 0;
    nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned));
    auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(coordinate_count);
    for (unsigned i = 0; i < coordinate_count; ++i)
    {
        nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
        coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
        BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
        BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
    }
    nodes_input_stream.close();
    return coords;
}
Пример #3
0
SegmentInformation getTestInfo(int lat, int lon, bool necessary)
{
    return SegmentInformation(FixedPointCoordinate(lat, lon), 0, 0, 0, TurnInstruction::HeadOn,
                              necessary, false, 0);
}
Пример #4
0
Handle<Value> Query::New(Arguments const& args)
{
    HandleScope scope;
    if (!args.IsConstructCall()) {
        return ThrowException(Exception::Error(String::New("Cannot call constructor as function, you need to use 'new' keyword")));
    }
    try {
        if (args.Length() != 1) {
            return ThrowException(Exception::TypeError(String::New("please provide an object of options for the first argument")));
        }
        if (!args[0]->IsObject()) {
            return ThrowException(Exception::TypeError(String::New("first argument must be an object")));
        }
        Local<Object> obj = args[0]->ToObject();
        if (obj->IsNull() || obj->IsUndefined()) {
            return ThrowException(Exception::TypeError(String::New("first arg must be an object")));
        }
        if (!obj->Has(String::NewSymbol("coordinates"))) {
            return ThrowException(Exception::TypeError(String::New("must provide a coordinates property")));
        }
        Local<Value> coordinates = obj->Get(String::New("coordinates"));
        if (!coordinates->IsArray()) {
            return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
        }
        Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
        if (coordinates_array->Length() < 2) {
            return ThrowException(Exception::TypeError(String::New("at least two coordinates must be provided")));
        }

        Query* q = new Query();
        q->this_->zoomLevel = 18; //no generalization
        q->this_->printInstructions = true; //turn by turn instructions
        q->this_->alternateRoute = true; //get an alternate route, too
        q->this_->geometry = true; //retrieve geometry of route
        q->this_->compression = true; //polyline encoding
        q->this_->checkSum = UINT_MAX; //see wiki
        q->this_->service = "viaroute"; //that's routing
        q->this_->outputFormat = "json";
        q->this_->jsonpParameter = ""; //set for jsonp wrapping
        q->this_->language = ""; //unused atm

        if (obj->Has(String::NewSymbol("alternateRoute"))) {
            q->this_->alternateRoute = obj->Get(String::New("alternateRoute"))->BooleanValue();
        }

        for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
            Local<Value> coordinate = coordinates_array->Get(i);
            if (!coordinate->IsArray()) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }
            Local<Array> coordinate_array = Local<Array>::Cast(coordinate);
            if (coordinate_array->Length() != 2) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }
            q->this_->coordinates.push_back(
                FixedPointCoordinate(coordinate_array->Get(0)->NumberValue()*COORDINATE_PRECISION,
                                     coordinate_array->Get(1)->NumberValue()*COORDINATE_PRECISION));
        }

        q->Wrap(args.This());
        return args.This();
    } catch (std::exception const& ex) {
        return ThrowException(Exception::TypeError(String::New(ex.what())));
    }
    return Undefined();
}
Пример #5
0
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
{
    std::mt19937 mt_rand(RANDOM_SEED);
    std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
    std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
    std::vector<FixedPointCoordinate> queries;
    for (unsigned i = 0; i < num_queries; i++)
    {
        queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
    }

    {
        const unsigned num_results = 5;
        std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
                  << " phantom nodes"
                  << "\n";

        TIMER_START(query_phantom);
        std::vector<PhantomNode> phantom_node_vector;
        for (const auto &q : queries)
        {
            phantom_node_vector.clear();
            rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
            phantom_node_vector.clear();
            rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
        }
        TIMER_STOP(query_phantom);

        std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
                  << " queries."
                  << "\n";
        std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
                  << "\n";

        std::cout << "#### LocateClosestEndPointForCoordinate"
                  << "\n";
    }

    TIMER_START(query_endpoint);
    FixedPointCoordinate result;
    for (const auto &q : queries)
    {
        rtree.LocateClosestEndPointForCoordinate(q, result, 3);
    }
    TIMER_STOP(query_endpoint);

    std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
              << "\n";
    std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
              << "\n";

    std::cout << "#### FindPhantomNodeForCoordinate"
              << "\n";

    TIMER_START(query_node);
    for (const auto &q : queries)
    {
        PhantomNode phantom;
        rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
    }
    TIMER_STOP(query_node);

    std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries << " queries."
              << "\n";
    std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query."
              << "\n";

    {
        const unsigned num_results = 1;
        std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
                  << " phantom nodes"
                  << "\n";

        TIMER_START(query_phantom);
        std::vector<PhantomNode> phantom_node_vector;
        for (const auto &q : queries)
        {
            phantom_node_vector.clear();
            rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
            phantom_node_vector.clear();
            rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
        }
        TIMER_STOP(query_phantom);

        std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
                  << " queries."
                  << "\n";
        std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
                  << "\n";

        std::cout << "#### LocateClosestEndPointForCoordinate"
                  << "\n";
    }
}
Пример #6
0
    inline float GetMinDist(const FixedPointCoordinate &location) const
    {
        const bool is_contained = Contains(location);
        if (is_contained)
        {
            return 0.0f;
        }

        enum Direction
        {
            INVALID    = 0,
            NORTH      = 1,
            SOUTH      = 2,
            EAST       = 4,
            NORTH_EAST = 5,
            SOUTH_EAST = 6,
            WEST       = 8,
            NORTH_WEST = 9,
            SOUTH_WEST = 10
        };

        Direction d = INVALID;
        if (location.lat > max_lat)
            d = (Direction) (d | NORTH);
        else if (location.lat < min_lat)
            d = (Direction) (d | SOUTH);
        if (location.lon > max_lon)
            d = (Direction) (d | EAST);
        else if (location.lon < min_lon)
            d = (Direction) (d | WEST);

        BOOST_ASSERT(d != INVALID);

        float min_dist = std::numeric_limits<float>::max();
        switch (d)
        {
            case NORTH:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon));
                break;
            case SOUTH:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon));
                break;
            case WEST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon));
                break;
            case EAST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon));
                break;
            case NORTH_EAST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon));
                break;
            case NORTH_WEST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon));
                break;
            case SOUTH_EAST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon));
                break;
            case SOUTH_WEST:
                min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon));
                break;
            default:
                break;
        }

        BOOST_ASSERT(min_dist != std::numeric_limits<float>::max());

        return min_dist;
    }
Пример #7
0
Handle<Value> Query::New(Arguments const& args)
{
    HandleScope scope;
    if (!args.IsConstructCall()) {
        return ThrowException(Exception::Error(String::New("Cannot call constructor as function, you need to use 'new' keyword")));
    }
    try {
        if (args.Length() != 1) {
            return ThrowException(Exception::TypeError(String::New("please provide an object of options for the first argument")));
        }
        if (!args[0]->IsObject()) {
            return ThrowException(Exception::TypeError(String::New("first argument must be an object")));
        }
        Local<Object> obj = args[0]->ToObject();
        if (obj->IsNull() || obj->IsUndefined()) {
            return ThrowException(Exception::TypeError(String::New("first arg must be an object")));
        }
        if (!obj->Has(String::New("coordinates"))) {
            return ThrowException(Exception::TypeError(String::New("must provide a coordinates property")));
        }
        Local<Value> coordinates = obj->Get(String::New("coordinates"));
        if (!coordinates->IsArray()) {
            return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
        }

        // Handle scenario in which caller explicitly specified service
        std::string service;
        if (obj->Has(String::New("service"))) {
            Local<Value> serviceValue = obj->Get(String::New("service"));
            v8::String::Utf8Value serviceUtf8Value(serviceValue->ToString());
            service = std::string(*serviceUtf8Value);
        }

        // Handle 'nearest', otherwise assume 'viaroute' service.
        if (service == "nearest" || service == "locate") {
            Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
            if (coordinates_array->Length() != 1) {
                return ThrowException(Exception::TypeError(String::New("coordinates array should only have one lat/long pair for 'nearest' or 'locate' queries")));
            }
            Local<Value> coordinate = coordinates_array->Get(0);
            if (!coordinate->IsArray()) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }
            Local<Array> coordinate_array = Local<Array>::Cast(coordinate);
            if (coordinate_array->Length() != 2) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }

            Query* q = new Query();
            q->this_->service = service;
            q->this_->coordinates.push_back(
                FixedPointCoordinate(coordinate_array->Get(0)->NumberValue()*COORDINATE_PRECISION,
                                     coordinate_array->Get(1)->NumberValue()*COORDINATE_PRECISION));

            q->Wrap(args.This());
            return args.This();
        }


        Local<Array> coordinates_array = Local<Array>::Cast(coordinates);
        if (coordinates_array->Length() < 2) {
            return ThrowException(Exception::TypeError(String::New("at least two coordinates must be provided")));
        }

        Query* q = new Query();
        q->this_->zoomLevel = 18; //no generalization
        q->this_->printInstructions = false; //turn by turn instructions
        q->this_->alternateRoute = true; //get an alternate route, too
        q->this_->geometry = true; //retrieve geometry of route
        q->this_->compression = true; //polyline encoding
        q->this_->checkSum = UINT_MAX; //see wiki
        q->this_->service = "viaroute"; //that's routing
        q->this_->outputFormat = "json";
        q->this_->jsonpParameter = ""; //set for jsonp wrapping
        q->this_->language = ""; //unused atm

        if (obj->Has(String::New("alternateRoute"))) {
            q->this_->alternateRoute = obj->Get(String::New("alternateRoute"))->BooleanValue();
        }

        if (obj->Has(String::New("checksum"))) {
            q->this_->checkSum = static_cast<unsigned>(obj->Get(String::New("checksum"))->Uint32Value());
        }

        if (obj->Has(String::New("zoomLevel"))) {
            q->this_->zoomLevel = static_cast<short>(obj->Get(String::New("zoomLevel"))->Int32Value());
        }

        if (obj->Has(String::New("printInstructions"))) {
            q->this_->printInstructions = obj->Get(String::New("printInstructions"))->BooleanValue();
        }

        if (obj->Has(String::New("jsonpParameter"))) {
            q->this_->jsonpParameter = *v8::String::Utf8Value(obj->Get(String::New("jsonpParameter")));
        }

        if (obj->Has(String::New("hints"))) {
            Local<Value> hints = obj->Get(String::New("hints"));
            if (!hints->IsArray()) {
                return ThrowException(Exception::TypeError(String::New("hints must be an array of strings/null")));
            }
            Local<Array> hints_array = Local<Array>::Cast(hints);
            for (uint32_t i = 0; i < hints_array->Length(); ++i) {
                Local<Value> hint = hints_array->Get(i);
                if (hint->IsString()) {
                    q->this_->hints.push_back(*v8::String::Utf8Value(hint));
                } else if(hint->IsNull()){
                    q->this_->hints.push_back("");
                }else{
                    return ThrowException(Exception::TypeError(String::New("hint must be null or string")));
                }
            }
        }

        for (uint32_t i = 0; i < coordinates_array->Length(); ++i) {
            Local<Value> coordinate = coordinates_array->Get(i);
            if (!coordinate->IsArray()) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }
            Local<Array> coordinate_array = Local<Array>::Cast(coordinate);
            if (coordinate_array->Length() != 2) {
                return ThrowException(Exception::TypeError(String::New("coordinates must be an array of (lat/long) pairs")));
            }
            q->this_->coordinates.push_back(
                FixedPointCoordinate(coordinate_array->Get(0)->NumberValue()*COORDINATE_PRECISION,
                                     coordinate_array->Get(1)->NumberValue()*COORDINATE_PRECISION));
        }

        q->Wrap(args.This());
        return args.This();
    } catch (std::exception const& ex) {
        return ThrowException(Exception::TypeError(String::New(ex.what())));
    }
    return Undefined();
}