Include edge duration information.
This commit is contained in:
		
							parent
							
								
									f07da00dfe
								
							
						
					
					
						commit
						fc027417d8
					
				@ -69,7 +69,7 @@ using FloatLine = std::vector<detail::Point<double>>;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// from mapnik-vector-tile
 | 
					// from mapnik-vector-tile
 | 
				
			||||||
// Encodes a linestring using protobuf zigzag encoding
 | 
					// Encodes a linestring using protobuf zigzag encoding
 | 
				
			||||||
inline bool encodeLinestring(const FixedLine& line,
 | 
					inline bool encodeLinestring(const FixedLine &line,
 | 
				
			||||||
                             protozero::packed_field_uint32 &geometry,
 | 
					                             protozero::packed_field_uint32 &geometry,
 | 
				
			||||||
                             std::int32_t &start_x,
 | 
					                             std::int32_t &start_x,
 | 
				
			||||||
                             std::int32_t &start_y)
 | 
					                             std::int32_t &start_y)
 | 
				
			||||||
@ -145,6 +145,64 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
    // This hits the OSRM StaticRTree
 | 
					    // This hits the OSRM StaticRTree
 | 
				
			||||||
    const auto edges = facade.GetEdgesInBox(southwest, northeast);
 | 
					    const auto edges = facade.GetEdgesInBox(southwest, northeast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<int> used_weights;
 | 
				
			||||||
 | 
					    std::unordered_map<int, std::size_t> weight_offsets;
 | 
				
			||||||
 | 
					    uint8_t max_datasource_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Loop over all edges once to tally up all the attributes we'll need.
 | 
				
			||||||
 | 
					    // We need to do this so that we know the attribute offsets to use
 | 
				
			||||||
 | 
					    // when we encode each feature in the tile.
 | 
				
			||||||
 | 
					    for (const auto &edge : edges)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int forward_weight = 0, reverse_weight = 0;
 | 
				
			||||||
 | 
					        uint8_t forward_datasource = 0;
 | 
				
			||||||
 | 
					        uint8_t reverse_datasource = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (edge.forward_packed_geometry_id != SPECIAL_EDGEID)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::vector<EdgeWeight> forward_weight_vector;
 | 
				
			||||||
 | 
					            facade.GetUncompressedWeights(edge.forward_packed_geometry_id, forward_weight_vector);
 | 
				
			||||||
 | 
					            forward_weight = forward_weight_vector[edge.fwd_segment_position];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            std::vector<uint8_t> forward_datasource_vector;
 | 
				
			||||||
 | 
					            facade.GetUncompressedDatasources(edge.forward_packed_geometry_id,
 | 
				
			||||||
 | 
					                                              forward_datasource_vector);
 | 
				
			||||||
 | 
					            forward_datasource = forward_datasource_vector[edge.fwd_segment_position];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (weight_offsets.find(forward_weight) == weight_offsets.end())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                used_weights.push_back(forward_weight);
 | 
				
			||||||
 | 
					                weight_offsets[forward_weight] = used_weights.size() - 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (edge.reverse_packed_geometry_id != SPECIAL_EDGEID)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::vector<EdgeWeight> reverse_weight_vector;
 | 
				
			||||||
 | 
					            facade.GetUncompressedWeights(edge.reverse_packed_geometry_id, reverse_weight_vector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            BOOST_ASSERT(edge.fwd_segment_position < reverse_weight_vector.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            reverse_weight =
 | 
				
			||||||
 | 
					                reverse_weight_vector[reverse_weight_vector.size() - edge.fwd_segment_position - 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (weight_offsets.find(reverse_weight) == weight_offsets.end())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                used_weights.push_back(reverse_weight);
 | 
				
			||||||
 | 
					                weight_offsets[reverse_weight] = used_weights.size() - 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            std::vector<uint8_t> reverse_datasource_vector;
 | 
				
			||||||
 | 
					            facade.GetUncompressedDatasources(edge.reverse_packed_geometry_id,
 | 
				
			||||||
 | 
					                                              reverse_datasource_vector);
 | 
				
			||||||
 | 
					            reverse_datasource = reverse_datasource_vector[reverse_datasource_vector.size() -
 | 
				
			||||||
 | 
					                                                           edge.fwd_segment_position - 1];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Keep track of the highest datasource seen so that we don't write unnecessary
 | 
				
			||||||
 | 
					        // data to the layer attribute values
 | 
				
			||||||
 | 
					        max_datasource_id = std::max(max_datasource_id, forward_datasource);
 | 
				
			||||||
 | 
					        max_datasource_id = std::max(max_datasource_id, reverse_datasource);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: extract speed values for compressed and uncompressed geometries
 | 
					    // TODO: extract speed values for compressed and uncompressed geometries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Convert tile coordinates into mercator coordinates
 | 
					    // Convert tile coordinates into mercator coordinates
 | 
				
			||||||
@ -152,8 +210,6 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
                            max_lat);
 | 
					                            max_lat);
 | 
				
			||||||
    const detail::BBox tile_bbox{min_lon, min_lat, max_lon, max_lat};
 | 
					    const detail::BBox tile_bbox{min_lon, min_lat, max_lon, max_lat};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t max_datasource_id = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Protobuf serialized blocks when objects go out of scope, hence
 | 
					    // Protobuf serialized blocks when objects go out of scope, hence
 | 
				
			||||||
    // the extra scoping below.
 | 
					    // the extra scoping below.
 | 
				
			||||||
    protozero::pbf_writer tile_writer{pbf_buffer};
 | 
					    protozero::pbf_writer tile_writer{pbf_buffer};
 | 
				
			||||||
@ -224,8 +280,9 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
                max_datasource_id = std::max(max_datasource_id, forward_datasource);
 | 
					                max_datasource_id = std::max(max_datasource_id, forward_datasource);
 | 
				
			||||||
                max_datasource_id = std::max(max_datasource_id, reverse_datasource);
 | 
					                max_datasource_id = std::max(max_datasource_id, reverse_datasource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const auto encode_tile_line = [&layer_writer, &edge, &id](
 | 
					                const auto encode_tile_line = [&layer_writer, &edge, &id, &max_datasource_id](
 | 
				
			||||||
                    const detail::FixedLine &tile_line, const std::uint32_t speed_kmh, const std::uint8_t datasource,
 | 
					                    const detail::FixedLine &tile_line, const std::uint32_t speed_kmh,
 | 
				
			||||||
 | 
					                    const std::size_t duration, const std::uint8_t datasource,
 | 
				
			||||||
                    std::int32_t &start_x, std::int32_t &start_y)
 | 
					                    std::int32_t &start_x, std::int32_t &start_y)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Here, we save the two attributes for our feature: the speed and the
 | 
					                    // Here, we save the two attributes for our feature: the speed and the
 | 
				
			||||||
@ -255,6 +312,9 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
                                          (edge.component.is_tiny ? 0 : 1)); // is_small feature
 | 
					                                          (edge.component.is_tiny ? 0 : 1)); // is_small feature
 | 
				
			||||||
                        field.add_element(2);                // "datasource" tag key offset
 | 
					                        field.add_element(2);                // "datasource" tag key offset
 | 
				
			||||||
                        field.add_element(130 + datasource); // datasource value offset
 | 
					                        field.add_element(130 + datasource); // datasource value offset
 | 
				
			||||||
 | 
					                        field.add_element(3);                // "duration" tag key offset
 | 
				
			||||||
 | 
					                        field.add_element(130 + max_datasource_id + 1 +
 | 
				
			||||||
 | 
					                                          duration); // duration value offset
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        // Encode the geometry for the feature
 | 
					                        // Encode the geometry for the feature
 | 
				
			||||||
@ -274,7 +334,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
                        static_cast<std::uint32_t>(round(length / forward_weight * 10 * 3.6));
 | 
					                        static_cast<std::uint32_t>(round(length / forward_weight * 10 * 3.6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
 | 
					                    auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
 | 
				
			||||||
                    encode_tile_line(tile_line, speed_kmh, forward_datasource, start_x, start_y);
 | 
					                    encode_tile_line(tile_line, speed_kmh, weight_offsets[forward_weight],
 | 
				
			||||||
 | 
					                                     forward_datasource, start_x, start_y);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Repeat the above for the coordinates reversed and using the `reverse`
 | 
					                // Repeat the above for the coordinates reversed and using the `reverse`
 | 
				
			||||||
@ -289,7 +350,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
                        static_cast<std::uint32_t>(round(length / reverse_weight * 10 * 3.6));
 | 
					                        static_cast<std::uint32_t>(round(length / reverse_weight * 10 * 3.6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
 | 
					                    auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
 | 
				
			||||||
                    encode_tile_line(tile_line, speed_kmh, reverse_datasource, start_x, start_y);
 | 
					                    encode_tile_line(tile_line, speed_kmh, weight_offsets[reverse_weight],
 | 
				
			||||||
 | 
					                                     reverse_datasource, start_x, start_y);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -300,19 +362,18 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
        layer_writer.add_string(3, "speed");
 | 
					        layer_writer.add_string(3, "speed");
 | 
				
			||||||
        layer_writer.add_string(3, "is_small");
 | 
					        layer_writer.add_string(3, "is_small");
 | 
				
			||||||
        layer_writer.add_string(3, "datasource");
 | 
					        layer_writer.add_string(3, "datasource");
 | 
				
			||||||
 | 
					        layer_writer.add_string(3, "duration");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Now, we write out the possible speed value arrays and possible is_tiny
 | 
					        // Now, we write out the possible speed value arrays and possible is_tiny
 | 
				
			||||||
        // values.  Field type 4 is the "values" field.  It's a variable type field,
 | 
					        // values.  Field type 4 is the "values" field.  It's a variable type field,
 | 
				
			||||||
        // so requires a two-step write (create the field, then write its value)
 | 
					        // so requires a two-step write (create the field, then write its value)
 | 
				
			||||||
        for (std::size_t i = 0; i < 128; i++)
 | 
					        for (std::size_t i = 0; i < 128; i++)
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Writing field type 4 == variant type
 | 
					            // Writing field type 4 == variant type
 | 
				
			||||||
            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
					            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
				
			||||||
            // Attribute value 5 == uin64 type
 | 
					            // Attribute value 5 == uin64 type
 | 
				
			||||||
            values_writer.add_uint64(5, i);
 | 
					            values_writer.add_uint64(5, i);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
					            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
				
			||||||
            // Attribute value 7 == bool type
 | 
					            // Attribute value 7 == bool type
 | 
				
			||||||
@ -324,13 +385,20 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
 | 
				
			|||||||
            values_writer.add_bool(7, false);
 | 
					            values_writer.add_bool(7, false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (std::size_t i = 0; i <= max_datasource_id; i++)
 | 
					        for (std::size_t i = 0; i <= max_datasource_id; i++)
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Writing field type 4 == variant type
 | 
					            // Writing field type 4 == variant type
 | 
				
			||||||
            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
					            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
				
			||||||
            // Attribute value 1 == string type
 | 
					            // Attribute value 1 == string type
 | 
				
			||||||
            values_writer.add_string(1, facade.GetDatasourceName(i));
 | 
					            values_writer.add_string(1, facade.GetDatasourceName(i));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        for (auto weight : used_weights)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Writing field type 4 == variant type
 | 
				
			||||||
 | 
					            protozero::pbf_writer values_writer(layer_writer, 4);
 | 
				
			||||||
 | 
					            // Attribute value 2 == float type
 | 
				
			||||||
 | 
					            // Durations come out of OSRM in integer deciseconds, so we convert them
 | 
				
			||||||
 | 
					            // to seconds with a simple /10 for display
 | 
				
			||||||
 | 
					            values_writer.add_double(3, weight / 10.);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user