{"action":"created","comment":{"url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/comments/25669484","id":25669484,"diff_hunk":"@@ -0,0 +1,314 @@\n+/*\n+\n+Copyright (c) 2015, Project OSRM contributors\n+All rights reserved.\n+\n+Redistribution and use in source and binary forms, with or without modification,\n+are permitted provided that the following conditions are met:\n+\n+Redistributions of source code must retain the above copyright notice, this list\n+of conditions and the following disclaimer.\n+Redistributions in binary form must reproduce the above copyright notice, this\n+list of conditions and the following disclaimer in the documentation and/or\n+other materials provided with the distribution.\n+\n+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\n+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+*/\n+\n+#ifndef MAP_MATCHING_PLUGIN_HPP\n+#define MAP_MATCHING_PLUGIN_HPP\n+\n+#include \"plugin_base.hpp\"\n+\n+#include \"../algorithms/bayes_classifier.hpp\"\n+#include \"../algorithms/object_encoder.hpp\"\n+#include \"../data_structures/search_engine.hpp\"\n+#include \"../descriptors/descriptor_base.hpp\"\n+#include \"../descriptors/json_descriptor.hpp\"\n+#include \"../routing_algorithms/map_matching.hpp\"\n+#include \"../util/compute_angle.hpp\"\n+#include \"../util/integer_range.hpp\"\n+#include \"../util/simple_logger.hpp\"\n+#include \"../util/json_logger.hpp\"\n+#include \"../util/json_util.hpp\"\n+#include \"../util/string_util.hpp\"\n+\n+#include <cstdlib>\n+\n+#include <algorithm>\n+#include <memory>\n+#include <string>\n+#include <vector>\n+\n+template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin\n+{\n+  private:\n+    std::shared_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;\n+\n+    using ClassifierT = BayesClassifier<LaplaceDistribution, LaplaceDistribution, double>;\n+    using TraceClassification = ClassifierT::ClassificationT;\n+\n+  public:\n+    MapMatchingPlugin(DataFacadeT *facade, const int max_locations_map_matching)\n+    : descriptor_string(\"match\")\n+    , facade(facade)\n+    , max_locations_map_matching(max_locations_map_matching)\n+    // the values where derived from fitting a laplace distribution\n+    // to the values of manually classified traces\n+    , classifier(LaplaceDistribution(0.0057154021891018675, 0.020294704891166186),\n+                 LaplaceDistribution(0.11467696742821254, 0.49918444000368756),\n+                 0.7977883096366508) // valid apriori probability\n+    {\n+        search_engine_ptr = std::make_shared<SearchEngine<DataFacadeT>>(facade);\n+    }\n+\n+    virtual ~MapMatchingPlugin() { }\n+\n+    const std::string GetDescriptor() const final { return descriptor_string; }\n+\n+    TraceClassification classify(float trace_length, float matched_length, int removed_points) const\n+    {\n+        double distance_feature = -std::log(trace_length) + std::log(matched_length);\n+\n+        // matched to the same point\n+        if (!std::isfinite(distance_feature))\n+        {\n+            return std::make_pair(ClassifierT::ClassLabel::NEGATIVE, 1.0);\n+        }\n+\n+        auto label_with_confidence =  classifier.classify(distance_feature);\n+\n+        // \"second stage classifier\": if we need to remove points there is something fishy\n+        if (removed_points > 0)\n+        {\n+            return std::make_pair(ClassifierT::ClassLabel::NEGATIVE, 1.0);\n+        }\n+\n+        return label_with_confidence;\n+    }\n+\n+    bool getCandiates(const std::vector<FixedPointCoordinate>& input_coords, std::vector<double>& sub_trace_lengths, Matching::CandidateLists& candidates_lists)\n+    {\n+        double last_distance = coordinate_calculation::great_circle_distance(\n+            input_coords[0],\n+            input_coords[1]);\n+        sub_trace_lengths.resize(input_coords.size());\n+        sub_trace_lengths[0] = 0;\n+        for (const auto current_coordinate : osrm::irange<std::size_t>(0, input_coords.size()))\n+        {\n+            bool allow_uturn = false;\n+            if (0 < current_coordinate)\n+            {\n+                last_distance = coordinate_calculation::great_circle_distance(\n+                    input_coords[current_coordinate - 1],\n+                    input_coords[current_coordinate]);\n+                sub_trace_lengths[current_coordinate] += sub_trace_lengths[current_coordinate-1] + last_distance;\n+            }\n+\n+            if (input_coords.size()-1 > current_coordinate && 0 < current_coordinate)\n+            {\n+                double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(\n+                                                    input_coords[current_coordinate-1],\n+                                                    input_coords[current_coordinate],\n+                                                    input_coords[current_coordinate+1]);\n+\n+                // sharp turns indicate a possible uturn\n+                if (turn_angle < 100.0 || turn_angle > 260.0)\n+                {\n+                    allow_uturn = true;\n+                }\n+            }\n+\n+            std::vector<std::pair<PhantomNode, double>> candidates;\n+            if (!facade->IncrementalFindPhantomNodeForCoordinateWithMaxDistance(\n+                    input_coords[current_coordinate],\n+                    candidates,\n+                    last_distance/2.0,\n+                    5,\n+                    Matching::max_number_of_candidates))\n+            {\n+                return false;\n+            }\n+\n+            if (allow_uturn)\n+            {\n+                candidates_lists.push_back(candidates);\n+            }\n+            else\n+            {\n+                unsigned compact_size = candidates.size();\n+                for (const auto i : osrm::irange(0u, compact_size))\n+                {\n+                    // Split edge if it is bidirectional and append reverse direction to end of list\n+                    if (candidates[i].first.forward_node_id != SPECIAL_NODEID\n+                     && candidates[i].first.reverse_node_id != SPECIAL_NODEID)\n+                    {\n+                        PhantomNode reverse_node(candidates[i].first);\n+                        reverse_node.forward_node_id = SPECIAL_NODEID;\n+                        candidates.push_back(std::make_pair(reverse_node, candidates[i].second));\n+\n+                        candidates[i].first.reverse_node_id = SPECIAL_NODEID;\n+                    }\n+                }\n+                candidates_lists.push_back(candidates);\n+            }\n+\n+        }\n+\n+        return true;\n+    }\n+\n+    osrm::json::Object submatchingToJSON(const Matching::SubMatching& sub, const RouteParameters& route_parameters, const InternalRouteResult& raw_route)\n+    {\n+        osrm::json::Object subtrace;\n+\n+        if (route_parameters.classify)\n+            subtrace.values[\"confidence\"] = sub.confidence;\n+\n+        if (route_parameters.geometry)\n+        {\n+            DescriptionFactory factory;\n+            FixedPointCoordinate current_coordinate;\n+            factory.SetStartSegment(\n+                raw_route.segment_end_coordinates.front().source_phantom,\n+                raw_route.source_traversed_in_reverse.front());\n+            for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size()))\n+            {\n+                for (const PathData &path_data : raw_route.unpacked_path_segments[i])\n+                {\n+                    current_coordinate = facade->GetCoordinateOfNode(path_data.node);\n+                    factory.AppendSegment(current_coordinate, path_data);\n+                }\n+                factory.SetEndSegment(raw_route.segment_end_coordinates[i].target_phantom,\n+                                      raw_route.target_traversed_in_reverse[i],\n+                                      raw_route.is_via_leg(i));\n+            }\n+            subtrace.values[\"geometry\"] = factory.AppendGeometryString(route_parameters.compression);\n+        }\n+\n+        subtrace.values[\"indices\"] = osrm::json::make_array(sub.indices);\n+\n+\n+        osrm::json::Array points;\n+        for (const auto& node : sub.nodes)\n+        {\n+            points.values.emplace_back(osrm::json::make_array(node.location.lat / COORDINATE_PRECISION,\n+                                                              node.location.lon / COORDINATE_PRECISION));\n+        }\n+        subtrace.values[\"matched_points\"] = points;\n+\n+        return subtrace;\n+    }\n+\n+    int HandleRequest(const RouteParameters &route_parameters, osrm::json::Object &json_result) final\n+    {\n+        // check number of parameters\n+        if (!check_all_coordinates(route_parameters.coordinates))\n+        {\n+            return 400;\n+        }\n+\n+        std::vector<double> sub_trace_lengths;\n+        Matching::CandidateLists candidates_lists;\n+        const auto& input_coords = route_parameters.coordinates;\n+        const auto& input_timestamps = route_parameters.timestamps;\n+        if (input_timestamps.size() > 0 && input_coords.size() != input_timestamps.size())\n+        {\n+            return 400;\n+        }\n+\n+        // enforce maximum number of locations for performance reasons\n+        if (max_locations_map_matching > 0 && static_cast<int>(input_coords.size()) > max_locations_map_matching)\n+        {\n+            return 400;\n+        }\n+\n+        bool found_candidates = getCandiates(input_coords, sub_trace_lengths, candidates_lists);\n+        if (!found_candidates)\n+        {\n+            return 400;\n+        }\n+\n+        // setup logging if enabled\n+        if (osrm::json::Logger::get())\n+            osrm::json::Logger::get()->initialize(\"matching\");\n+\n+        // call the actual map matching\n+        Matching::SubMatchingList sub_matchings;\n+        search_engine_ptr->map_matching(candidates_lists,\n+                                        input_coords,\n+                                        input_timestamps,\n+                                        route_parameters.matching_beta,\n+                                        route_parameters.gps_precision,\n+                                        sub_matchings);\n+\n+        if (1 > sub_matchings.size())\n+        {\n+            return 400;\n+        }\n+\n+        osrm::json::Array matchings;\n+        for (auto& sub : sub_matchings)\n+        {\n+            // classify result\n+            if (route_parameters.classify)\n+            {\n+                double trace_length = sub_trace_lengths[sub.indices.back()] - sub_trace_lengths[sub.indices.front()];\n+                TraceClassification classification = classify(trace_length,\n+                                                              sub.length,\n+                                                              (sub.indices.back() - sub.indices.front() + 1) - sub.nodes.size());\n+                if (classification.first == ClassifierT::ClassLabel::POSITIVE)","path":"plugins/map_matching.hpp","position":270,"original_position":270,"commit_id":"0d879ed2907714b0ffb0db7e42b87187ee7e5531","original_commit_id":"0d879ed2907714b0ffb0db7e42b87187ee7e5531","user":{"login":"DennisOSRM","id":1067895,"avatar_url":"https://avatars.githubusercontent.com/u/1067895?v=3","gravatar_id":"","url":"https://api.github.com/users/DennisOSRM","html_url":"https://github.com/DennisOSRM","followers_url":"https://api.github.com/users/DennisOSRM/followers","following_url":"https://api.github.com/users/DennisOSRM/following{/other_user}","gists_url":"https://api.github.com/users/DennisOSRM/gists{/gist_id}","starred_url":"https://api.github.com/users/DennisOSRM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DennisOSRM/subscriptions","organizations_url":"https://api.github.com/users/DennisOSRM/orgs","repos_url":"https://api.github.com/users/DennisOSRM/repos","events_url":"https://api.github.com/users/DennisOSRM/events{/privacy}","received_events_url":"https://api.github.com/users/DennisOSRM/received_events","type":"User","site_admin":false},"body":"Would it make sense to switch the two compared items? That way there wouldn't be an lvalue on the left-hand side and accidental assignments would (or could) not happen.","created_at":"2015-03-03T08:18:24Z","updated_at":"2015-03-03T08:18:24Z","html_url":"https://github.com/Project-OSRM/osrm-backend/pull/1407#discussion_r25669484","pull_request_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407","_links":{"self":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/comments/25669484"},"html":{"href":"https://github.com/Project-OSRM/osrm-backend/pull/1407#discussion_r25669484"},"pull_request":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407"}}},"pull_request":{"url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407","id":30334176,"html_url":"https://github.com/Project-OSRM/osrm-backend/pull/1407","diff_url":"https://github.com/Project-OSRM/osrm-backend/pull/1407.diff","patch_url":"https://github.com/Project-OSRM/osrm-backend/pull/1407.patch","issue_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/1407","number":1407,"state":"open","locked":false,"title":"Map Matching","user":{"login":"TheMarex","id":606968,"avatar_url":"https://avatars.githubusercontent.com/u/606968?v=3","gravatar_id":"","url":"https://api.github.com/users/TheMarex","html_url":"https://github.com/TheMarex","followers_url":"https://api.github.com/users/TheMarex/followers","following_url":"https://api.github.com/users/TheMarex/following{/other_user}","gists_url":"https://api.github.com/users/TheMarex/gists{/gist_id}","starred_url":"https://api.github.com/users/TheMarex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheMarex/subscriptions","organizations_url":"https://api.github.com/users/TheMarex/orgs","repos_url":"https://api.github.com/users/TheMarex/repos","events_url":"https://api.github.com/users/TheMarex/events{/privacy}","received_events_url":"https://api.github.com/users/TheMarex/received_events","type":"User","site_admin":false},"body":"Implements map matching based on ```\"Hidden Markov Map Matching Through Noise and Sparseness\"; P. Newson and J. Krumm; 2009; ACM```.\r\nThis can be used to match GPS traces to a road network. Note: Currently this works best with traces that have a sample frequency of about 10 samples/minute. You should make sure to remove blobs (accumulated GPS points, when standing still) and reduce the sample to 10 samples/minute.\r\nThe ```gps_precision``` and ```matching_beta``` parameters can be tuned to adapt the matching to your dataset.\r\n\r\nAPI additions:\r\n\r\n```\r\nt = UNIX_TIMESTAMP\r\ngps_precision = GPS_STANDART_DEVIATION (in meters, default: -1 which means auto)\r\nmatching_beta = DOUBLE  (see paper for details, default: -1 which means auto)\r\nclassify = BOOL (default: false enables computing confidence for the trace)\r\n```\r\n\r\nUsage:\r\n\r\n```\r\n/match?loc=lat1,lon1&t=0&loc=lat2,lon2&t=7&loc=lat3,lon3&t=14&geometry=false&classify=true\r\n```\r\n\r\nrouted parameter additions:\r\n\r\n```\r\n--max-locations-map-matching (default: -1 which means disabled)\r\n```\r\n","created_at":"2015-03-03T00:02:24Z","updated_at":"2015-03-03T08:18:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d174eb95758cf729760b1463f0547cea9a7f3d97","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407/commits","review_comments_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407/comments","review_comment_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/1407/comments","statuses_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/statuses/0d879ed2907714b0ffb0db7e42b87187ee7e5531","head":{"label":"Project-OSRM:feature/matching","ref":"feature/matching","sha":"0d879ed2907714b0ffb0db7e42b87187ee7e5531","user":{"login":"Project-OSRM","id":8207060,"avatar_url":"https://avatars.githubusercontent.com/u/8207060?v=3","gravatar_id":"","url":"https://api.github.com/users/Project-OSRM","html_url":"https://github.com/Project-OSRM","followers_url":"https://api.github.com/users/Project-OSRM/followers","following_url":"https://api.github.com/users/Project-OSRM/following{/other_user}","gists_url":"https://api.github.com/users/Project-OSRM/gists{/gist_id}","starred_url":"https://api.github.com/users/Project-OSRM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Project-OSRM/subscriptions","organizations_url":"https://api.github.com/users/Project-OSRM/orgs","repos_url":"https://api.github.com/users/Project-OSRM/repos","events_url":"https://api.github.com/users/Project-OSRM/events{/privacy}","received_events_url":"https://api.github.com/users/Project-OSRM/received_events","type":"Organization","site_admin":false},"repo":{"id":2436255,"name":"osrm-backend","full_name":"Project-OSRM/osrm-backend","owner":{"login":"Project-OSRM","id":8207060,"avatar_url":"https://avatars.githubusercontent.com/u/8207060?v=3","gravatar_id":"","url":"https://api.github.com/users/Project-OSRM","html_url":"https://github.com/Project-OSRM","followers_url":"https://api.github.com/users/Project-OSRM/followers","following_url":"https://api.github.com/users/Project-OSRM/following{/other_user}","gists_url":"https://api.github.com/users/Project-OSRM/gists{/gist_id}","starred_url":"https://api.github.com/users/Project-OSRM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Project-OSRM/subscriptions","organizations_url":"https://api.github.com/users/Project-OSRM/orgs","repos_url":"https://api.github.com/users/Project-OSRM/repos","events_url":"https://api.github.com/users/Project-OSRM/events{/privacy}","received_events_url":"https://api.github.com/users/Project-OSRM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Project-OSRM/osrm-backend","description":"Project OSRM: C++ backend","fork":false,"url":"https://api.github.com/repos/Project-OSRM/osrm-backend","forks_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/forks","keys_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/teams","hooks_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/hooks","issue_events_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/events{/number}","events_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/events","assignees_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/assignees{/user}","branches_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/branches{/branch}","tags_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/tags","blobs_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/refs{/sha}","trees_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/statuses/{sha}","languages_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/languages","stargazers_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/stargazers","contributors_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/contributors","subscribers_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/subscribers","subscription_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/subscription","commits_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/commits{/sha}","git_commits_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/commits{/sha}","comments_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/comments{/number}","issue_comment_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/comments{/number}","contents_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/contents/{+path}","compare_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/merges","archive_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/downloads","issues_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues{/number}","pulls_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls{/number}","milestones_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/milestones{/number}","notifications_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/labels{/name}","releases_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/releases{/id}","created_at":"2011-09-22T10:05:08Z","updated_at":"2015-03-02T23:42:28Z","pushed_at":"2015-03-02T23:50:36Z","git_url":"git://github.com/Project-OSRM/osrm-backend.git","ssh_url":"git@github.com:Project-OSRM/osrm-backend.git","clone_url":"https://github.com/Project-OSRM/osrm-backend.git","svn_url":"https://github.com/Project-OSRM/osrm-backend","homepage":"http://map.project-osrm.org","size":21475,"stargazers_count":711,"watchers_count":711,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":258,"mirror_url":null,"open_issues_count":174,"forks":258,"open_issues":174,"watchers":711,"default_branch":"master"}},"base":{"label":"Project-OSRM:develop","ref":"develop","sha":"7e00a86bb47dce69913bf27588b73d9a96dce254","user":{"login":"Project-OSRM","id":8207060,"avatar_url":"https://avatars.githubusercontent.com/u/8207060?v=3","gravatar_id":"","url":"https://api.github.com/users/Project-OSRM","html_url":"https://github.com/Project-OSRM","followers_url":"https://api.github.com/users/Project-OSRM/followers","following_url":"https://api.github.com/users/Project-OSRM/following{/other_user}","gists_url":"https://api.github.com/users/Project-OSRM/gists{/gist_id}","starred_url":"https://api.github.com/users/Project-OSRM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Project-OSRM/subscriptions","organizations_url":"https://api.github.com/users/Project-OSRM/orgs","repos_url":"https://api.github.com/users/Project-OSRM/repos","events_url":"https://api.github.com/users/Project-OSRM/events{/privacy}","received_events_url":"https://api.github.com/users/Project-OSRM/received_events","type":"Organization","site_admin":false},"repo":{"id":2436255,"name":"osrm-backend","full_name":"Project-OSRM/osrm-backend","owner":{"login":"Project-OSRM","id":8207060,"avatar_url":"https://avatars.githubusercontent.com/u/8207060?v=3","gravatar_id":"","url":"https://api.github.com/users/Project-OSRM","html_url":"https://github.com/Project-OSRM","followers_url":"https://api.github.com/users/Project-OSRM/followers","following_url":"https://api.github.com/users/Project-OSRM/following{/other_user}","gists_url":"https://api.github.com/users/Project-OSRM/gists{/gist_id}","starred_url":"https://api.github.com/users/Project-OSRM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Project-OSRM/subscriptions","organizations_url":"https://api.github.com/users/Project-OSRM/orgs","repos_url":"https://api.github.com/users/Project-OSRM/repos","events_url":"https://api.github.com/users/Project-OSRM/events{/privacy}","received_events_url":"https://api.github.com/users/Project-OSRM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Project-OSRM/osrm-backend","description":"Project OSRM: C++ backend","fork":false,"url":"https://api.github.com/repos/Project-OSRM/osrm-backend","forks_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/forks","keys_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/teams","hooks_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/hooks","issue_events_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/events{/number}","events_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/events","assignees_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/assignees{/user}","branches_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/branches{/branch}","tags_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/tags","blobs_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/refs{/sha}","trees_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/statuses/{sha}","languages_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/languages","stargazers_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/stargazers","contributors_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/contributors","subscribers_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/subscribers","subscription_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/subscription","commits_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/commits{/sha}","git_commits_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/git/commits{/sha}","comments_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/comments{/number}","issue_comment_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/comments{/number}","contents_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/contents/{+path}","compare_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/merges","archive_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/downloads","issues_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues{/number}","pulls_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls{/number}","milestones_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/milestones{/number}","notifications_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/labels{/name}","releases_url":"https://api.github.com/repos/Project-OSRM/osrm-backend/releases{/id}","created_at":"2011-09-22T10:05:08Z","updated_at":"2015-03-02T23:42:28Z","pushed_at":"2015-03-02T23:50:36Z","git_url":"git://github.com/Project-OSRM/osrm-backend.git","ssh_url":"git@github.com:Project-OSRM/osrm-backend.git","clone_url":"https://github.com/Project-OSRM/osrm-backend.git","svn_url":"https://github.com/Project-OSRM/osrm-backend","homepage":"http://map.project-osrm.org","size":21475,"stargazers_count":711,"watchers_count":711,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":258,"mirror_url":null,"open_issues_count":174,"forks":258,"open_issues":174,"watchers":711,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407"},"html":{"href":"https://github.com/Project-OSRM/osrm-backend/pull/1407"},"issue":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/1407"},"comments":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/issues/1407/comments"},"review_comments":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407/comments"},"review_comment":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/pulls/1407/commits"},"statuses":{"href":"https://api.github.com/repos/Project-OSRM/osrm-backend/statuses/0d879ed2907714b0ffb0db7e42b87187ee7e5531"}}}}