Read in other languages: English, Русский
Transport Directory - supports graphical output, route search and calculation of travel time.
First, requests to create a database are submitted for input, then requests to the database itself.
When creating a database with the -make_base
command, the result of building ** is serialized** and saved to the file specified in the serialization_settings
parameter.
Then, when the -process_requests
command is called from the file specified in the serialization_settings
parameter, the deserialization of the created database is performed and queries are executed.
Using queries, you can find out:
- which bus routes pass through the stop
- what stops are there on the bus route
- find out the shortest route between two stops
A person can use several buses on the route.
One bus can even be used several times if it makes a big detour in some sections and it is easier to cut off on another bus.
To build this project on linux you need:
1)If you don't have Cmake installed, install Cmake
2)For the application to work, you need to install Protobuf, here is the instruction || инструкция
2)If the "Debug" or "Release" folders are not created:
mkdir ../Debug
mkdir ../Release
3)Go to the transport-catalog
folder and run the command for Debug and/or Release conf:
❗ ❗ ❗
Change /path/to/protobuf/package
to the path to the protobuf you installed in the previous steps
cmake -E chdir ../Debug/ cmake -G "Unix Makefiles" ../transport-catalogue/ -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_PREFIX_PATH=/path/to/protobuf/package
cmake -E chdir ../Release/ cmake -G "Unix Makefiles" ../transport-catalogue -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_PREFIX_PATH=/path/to/protobuf/package
4)Go to "Debug" or "Release" folder and build:
cmake --build .
5)To Run program - in the debug or release folder run:
./transport_catalogue
- Installation and configuration of all required components in the development environment to run the application
- The use case is shown in main.cpp and when calling
./transport_catalogue -help
- Examples of input documents and answers to them are in the 'Examples` folder.
The task of the make_base program is to build a database and serialize it into a file with the specified name.
The input to the make_base program is JSON with the following keys:
- base_requests: Bus and Stop requests to create a database.
- render_settings: rendering settings.
- serialization_settings: serialization settings.
- routing_settings — routing settings, dictionary with two keys:
bus_wait_time — waiting time for the bus at the stop, in minutes.
bus_velocity — bus speed, in km/h.
The process_requests program should output JSON with responses to requests.
The process_requests program receives a JSON file with the following keys as input:
- stat_requests: Bus and Stop requests to the finished database.
- serialization_settings: serialization settings.
- Route — these are requests for building a route between two stops.
In addition to the standard id and type properties, they contain two more:
from — the stop where you need to start the route.
to — stop where you need to finish the route.
Both values are names of stops existing in the database. However, they may not belong to any bus route.
- C++17(STL)
- GCC (MinG w64) 11.2.0
- Add UI
- Replace the route search library
- Add the ability to offer multiple paths to choose from
- Hash functions, unordered_map and unordered_set
- Trees
- namespases
- JSON
- Smart pointers unique_ptr, shared_ptr and weak_ptr
- Inheritance and polymorphism, abstract classes, interfaces
- Runtime polymorphism with std::variant, dynamic type conversion
- Immediately invoked lambda expression, std::invoke
- mutable
- Working with paths and streams: input/output, string, for working with files
- Regular expressions std::regex
- RAII - "Resource Acquisition is Initialization”
- move-semantics, Forwarding reference
- Dense packaging, Serialization, deserialization, Google Protocol Buffers - Protobuf
- Table of virtual methods
- transport_catalogue.h, transport_catalogue.cpp — class of the transport directory
- main.cpp — entry point.
Two libraries were used in the work: - graph.h — class implementing weighted oriented graph
- router.h — class implementing shortest path search in weighted oriented graph
- domain.cpp ,domain.h - In this file, classes/structures that are part of the application domain and do not depend on the transport directory
- geo.cpp , geo.h - functions for working with geographical coordinates
- json.cpp ,json.h - developed simplified library for working with JSON
- json_builder.cpp , json_builder.h - necessary classes/structures to create an output file in JSON format
- json_reader.cpp , json_reader.h - necessary classes/structures for reading and processing the input file in JSON format
- log_duration.h - a file with a class that allows profiling
- map_renderer.cpp , map_renderer.h - code responsible for visualizing the route map in SVG format.
- serialization.cpp , serialization.h - necessary classes/structures for processing serialized files.
- svg.cpp ,svg.h - processing and storing SVG image parameters
- transport_router.cpp , transport_router.h - building routes
- transport_catalogue.proto, transport_router.protoF, svg.proto - proto files, for serialization
Data in JSON object format. Its top-level structure:
{
"base_requests": [ ... ],
"stat_requests": [ ... ]
}
This is a dictionary containing keys:
base_requests
- is an array with a description of bus routes and stops,
stat_requests
- is an array with requests to the transport directory.
The base_requests
array contains two types of elements: routes and stops. They are listed in any order.
{
"type": "Stop",
"name": "Электросети",
"latitude": 43.598701,
"longitude": 39.730623,
"road_distances": {
"Улица Докучаева": 3000,
"Улица Лизы Чайкиной": 4300
}
}
Description of the stop — dictionary with keys:
- type — string equal to "Stop". Means that the dictionary describes the situation;
- name — the name of the stop;
- latitude and longitude — latitude and longitude of the stop — floating point numbers;
- road_distances — a dictionary that specifies the road distance from this stop to neighboring ones. Each key in this dictionary is the name of a nearby stop, the value is an integer distance in meters.
{
"type": "Bus",
"name": "14",
"stops": [
"Улица Лизы Чайкиной",
"Электросети",
"Улица Докучаева",
"Улица Лизы Чайкиной"
],
"is_roundtrip": true
}
Description of the bus route — dictionary with keys:
- type — string "Bus". Means that the dictionary describes the bus route;
- name — the name of the route;
- stops — an array with the names of stops that the route passes through. For a circular route, the name of the last stop duplicates the name of the first one. For example: ["stop1", "stop2", "stop3", "stop1"];
- is_roundtrip — value of the bool type. true if the route is circular.
Requests are stored in the stat_requests
array. In response to them, the program should output a JSON array of responses to stdout:
[
{ response to the first request },
{ response to the second request },
...
{ response to the last request }
]
Each query is a dictionary with the required keys id
and type
. They specify a unique numeric identifier of the request and its type. There may be other keys in the dictionary that are specific to a particular type of query.
In the output JSON array, each stat_requests
request must have a dictionary response with the mandatory request_id
key. The key value must be equal to the id
of the corresponding request. There are other keys in the dictionary that are specific to a particular type of response.
The order of responses to requests in the output array must match the order of requests in the stat_requests
array.
Request format:
{
"id": 12345678,
"type": "Bus",
"name": "14"
}
The type key has the value “Bus". It can be used to determine that this is a request for route information.
The name key specifies the name of the route for which the application should output statistical information.
{
"curvature": 2.18604,
"request_id": 12345678,
"route_length": 9300,
"stop_count": 4,
"unique_stop_count": 3
}
Dictionary Keys:
- curvature — the tortuosity of the route. It is equal to the ratio of the length of the road distance of the route to the length of the geographical distance. A number of type double;
- request_id — must be equal to the id of the corresponding Bus request. Integer;
- route_length — the length of the road distance of the route in meters, integer;
- stop_count — the number of stops on the route;
- unique_stop_count — the number of unique stops on the route.
For example, on a circular route with stops A, B, C, A there are four stops. Three of them are unique.
There are five stops on the ring route with stops A, B and C (A, B, C, B, A). Three of them are unique.
If there is no route with the specified name in the directory, the answer will be as follows:
{
"request_id": 12345678,
"error_message": "not found"
}
Request format:
{
"id": 12345,
"type": "Stop",
"name": "Улица Докучаева"
}
The name key sets the name of the stop.
{
"buses": [
"14", "22к"
],
"request_id": 12345
}
The value of the response keys:
- buses - is an array of names of routes that pass through this stop. The names are sorted in lexicographic order.
- request_id - is an integer equal to the id of the corresponding Stop request.
If there is no stop with the given name in the directory, the response to the request should be as follows:
{
"request_id": 12345,
"error_message": "not found"
}
{
"width": 1200.0,
"height": 1200.0,
"padding": 50.0,
"line_width": 14.0,
"stop_radius": 5.0,
"bus_label_font_size": 20,
"bus_label_offset": [7.0, 15.0],
"stop_label_font_size": 20,
"stop_label_offset": [7.0, -3.0],
"underlayer_color": [255, 255, 255, 0.85],
"underlayer_width": 3.0,
"color_palette": [
"green",
[255, 160, 0],
"red"
]
}
- width and height — the width and height of the image in pixels. A real number in the range from 0 to 100000.
- padding — the padding of the edges of the map from the borders of the SVG document. A real number no less then 0 and less than min(width, height)/2.
- line_width — the thickness of the lines that draw bus routes. A real number in the range from 0 to 100000.
- stop_radius — radius of circles that indicate stops. A real number in the range from 0 to 100000.
- bus_label_font_size — the size of the text used to write the names of bus routes. An integer in the range from 0 to 100000.
- bus_label_offset — offset of the route name label relative to the coordinates of the final stop on the map. An array of two elements of the double type. Sets the values of the dx and dy properties of the SVG element. Array elements are numbers in the range from -100000 to 100000.
- stop_label_font_size — the size of the text that displays the names of stops. An integer in the range from 0 to 100000.
- stop_label_offset — offset of the name of the stop relative to its coordinates on the map. An array of two elements of the double type. Sets the values of the dx and dy properties of the SVG element. Numbers in the range from -100000 to 100000.
- underlayer_color — the color of the background under the names of stops and routes. The color storage format will be below.
underlayer_width — the thickness of the substrate under the names of stops and routes. Sets the value of the stroke-width attribute of the element. A real number in the range from 0 to 100000.
- color_palette — color palette. A non-empty array.
The color can be specified in one of the following formats:
- in the form of a string, for example, "red" or "black";
- in an array of three integers in the range [0, 255]. They define the r, g and b components of the color in svg::Rgb format. The color [255, 16, 12] should be output in SVG as rgb(255,16,12);
- in an array of four elements: three integers in the range from [0, 255] and one real number in the range from [0.0, 1.0]. They set the components red, green, blue and opacity colors of the svg::Rgba format. The color specified as [255, 200, 23, 0.85], should be output in SVG as rgba(255,200,23,0.85).
{
"type": "Map",
"id": 11111
}
{
"map": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <polyline points=\"100.817,170 30,30 100.817,170\" fill=\"none\" stroke=\"green\" stroke-width=\"14\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <text fill=\"rgba(255,255,255,0.85)\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" x=\"100.817\" y=\"170\" dx=\"7\" dy=\"15\" font-size=\"20\" font-family=\"Verdana\" font-weight=\"bold\">114</text>\n <text fill=\"green\" x=\"100.817\" y=\"170\" dx=\"7\" dy=\"15\" font-size=\"20\" font-family=\"Verdana\" font-weight=\"bold\">114</text>\n <text fill=\"rgba(255,255,255,0.85)\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" x=\"30\" y=\"30\" dx=\"7\" dy=\"15\" font-size=\"20\" font-family=\"Verdana\" font-weight=\"bold\">114</text>\n <text fill=\"green\" x=\"30\" y=\"30\" dx=\"7\" dy=\"15\" font-size=\"20\" font-family=\"Verdana\" font-weight=\"bold\">114</text>\n <circle cx=\"100.817\" cy=\"170\" r=\"5\" fill=\"white\"/>\n <circle cx=\"30\" cy=\"30\" r=\"5\" fill=\"white\"/>\n <text fill=\"rgba(255,255,255,0.85)\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" x=\"100.817\" y=\"170\" dx=\"7\" dy=\"-3\" font-size=\"20\" font-family=\"Verdana\">Морской вокзал</text>\n <text fill=\"black\" x=\"100.817\" y=\"170\" dx=\"7\" dy=\"-3\" font-size=\"20\" font-family=\"Verdana\">Морской вокзал</text>\n <text fill=\"rgba(255,255,255,0.85)\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" x=\"30\" y=\"30\" dx=\"7\" dy=\"-3\" font-size=\"20\" font-family=\"Verdana\">Ривьерский мост</text>\n <text fill=\"black\" x=\"30\" y=\"30\" dx=\"7\" dy=\"-3\" font-size=\"20\" font-family=\"Verdana\">Ривьерский мост</text>\n</svg>",
"request_id": 11111
}
The map key is a string with a map image in SVG format.