#pragma once #include "StreetsDatabaseAPI.h" #include "OSMDatabaseAPI.h" #include "ezgl/application.hpp" #include "ezgl/graphics.hpp" #include <stdbool.h> #include <time.h> #include <cmath> #include <cstring> #include <string> #include <vector> #include <unordered_set> #include <unordered_map> #include <utility> #include <chrono> #include <queue> #define NO_EDGE -1 #define UNVISITED -1 #define BIG_MAP 1000000 // create a struct that is a type holding a latlon position and string name struct intersection_data { LatLon position; std::string name; }; // holds node data for priority queue struct WaveElem { // public WaveElem nodes IntersectionIdx nodeID; StreetSegmentIdx edgeID; double travelTime = 0.0; // double mileage; // WaveElem constructor WaveElem(int n, int e, double time) { nodeID = n; edgeID = e; travelTime = time; // mileage = m; } }; // struct used as overloaded operator for Less comparator in priority queue struct FriendElem { //overloaded operator for WaveElem comparison bool operator()(const WaveElem &lhs, const WaveElem &rhs) { return ((lhs.travelTime) > (rhs.travelTime )); } }; // node for A* algorithm class Node { public: StreetSegmentIdx reachingEdge; double bestTime = UNVISITED; double bestMileage = UNVISITED; }; struct CourrierNode { bool isPickup = false; IntersectionIdx destination = -1; std::vector<StreetSegmentIdx> path; }; // Global variable definitions are listed below. Note: extern keyword marks that this // global variable can be used in a different file, and the two // will be connected if they have the same definition extern std::vector<std::vector<StreetSegmentIdx>> segmentsInIntersections; extern std::unordered_set<StreetSegmentIdx> allSegments; extern std::vector<std::unordered_set<IntersectionIdx>> streetIntersections; extern std::vector<std::pair<StreetIdx, std::string>> streetNames; extern std::vector<std::vector<ezgl::point2d>> featuresInPoint2d; extern std::vector<double> streetLengths; extern std::vector<double> timeTravel; extern std::vector<std::pair<FeatureIdx, double>> sortedFeaturesArea; extern std::unordered_map<OSMID, LatLon> OSMContent; extern std::unordered_map<FeatureIdx, double> featureMin; extern std::unordered_map<FeatureIdx, double> featureMax; extern std::vector<const OSMWay *> osm_highways; extern std::vector<const OSMWay *> osm_main_roads; extern std::vector<const OSMWay *> osm_residential; extern std::vector<const OSMRelation *> osm_subway_lines; extern std::vector<std::vector<TypedOSMID>> all_route_members; extern std::vector<ezgl::point2d> intersectionPoint2d; extern std::vector<TypedOSMID> all_stations; extern std::vector<ezgl::point2d> subwayStationsxy; extern std::vector<struct intersection_data> intersections; extern std::vector<StreetSegmentIdx> segPath; extern std::vector<Node> nodes; extern double max_lat; extern double min_lat; extern double max_lon; extern double min_lon; extern float avgLat; extern bool noSubways; extern double maxSpeedLimit; // populateSegments populates the segmentsInIntersections global variable. The // indices in this vector represent the interesection IDs (IntersectionIdx) // for convenince. The nested vectors represent all of the // street segments connected to the interesection by their // street segment ID (streetSegmentIdx) void populateSegments(); // populateAllSegments populates a vector to store all street segments of a street // this is for convience to compute the total length of streets void populateAllSegments(); // populateStreetIntersections populates the streetIntersections global variable. // The streetIntersections vector is mapped so that the index represents the street ID (StreetIdx), and the // value is an unordered set of the intersections. Note: the unordered set was chosen // so that insertion produced no duplicates void populateStreetIntersections(); // populateStreetNames populates the streetNames global variable. // The streetNames vector is mapped so that it is in pairs of (StreetIdx(Street ID), streetName). void populateStreetNames(); // populateOSMContent populates the OSMContent global variable. The data is stored in key-value // pairs of (OSMID, LatLon) and fetched from the OSM API void populateOSMContent(); // find an index where streetName contains a given prefix. (Binary Search) // more matches of the prefix can be contained in indicies left OR right to the found index. int findPartialLocations(std::string street_prefix); // asciiToLower is called with a char argument and returns the corresponding lowercase // equivalent char of the argument char asciiToLower(char c); // make sure std::sort method sorts by Street Name (alphabetically), not by Street_ID // when sorting through streetNames vector bool sortbysec(const std::pair<StreetIdx, std::string> &a, const std::pair<StreetIdx, std::string> &b); // make sure std::sort method sorts Features by its size, not by streetid bool sortfeaturebysec(const std::pair<int, double> &a, const std::pair<int, double> &b); // removeSpaces takes a constant string argument to be parsed and returns // the argument in a form without whitespace std::string removeSpaces(const std::string &s); // parseName takes a string argument and calls both asciiToLower and removeSpaces , // then returns a string wihthout capital letters or whitespace std::string parseName(std::string name); // getHour gets the current hour in local time int getHour(); // loadSOMRoads loops through all OSM ways to find the roads in the city // there are 3 categories, highways, main roads, and residential roads // they are differentiated by tags and are all stored into their respective // global vectors void loadOSMRoads(); // loadOSMSubwayRoutes loops through all OSM Relations to get subway routes // stores subway station locations in a vector of OSMRelations void loadOSMSubwayRoutes(); // loadAllSubwayRouteNodeMembers takes a vector of OSMRelations and searches // through the vector to find OSMNodes which represent the subway stations and // put them into another global vector void loadAllSubwayRouteNodeMembers(); // populateSubwayStationLatLon takes the OSMNode and gets the xy coordinates // storing them in a vector of all station points in xy coords void populateSubwayStationLatLon(); // setLineWidths void setLineWidths(int &road, int &mainRoad, int &highwayRoad, std::vector<int> &roadColor, std::vector<int> &mainRoadColor, std::vector<int> &highwayRoadColor, int curr, bool light_mode); // getLineWidth int getLineWidth(int curr, int prev, int initial, int zoomFrequency, int zoomLevel, int widthChange, int lineWidth); // resetZoom bool resetZoom(int curr, int &prev, int &initial, int zoomFrequency, int &zoomLevel); // initialZoom void initialZoom(int &initial, int &road, int &mainRoad, int &highwayRoad, int &zoomLevel); // function computes x coordinate from longitude float x_from_lon(float lon); // function computes y corrdinate from latitude float y_from_lat(float lat); // latlon_to_point2d converts latlon to xy ezgl::point2d latlon_to_point2d(LatLon point); // point2d_to_latlon converts xy to latlon LatLon point2d_to_latlon(ezgl::point2d point); // intersection_to_point2d converts an intersection into type point2d void intersection_to_point2d(); // avgLatFinder finds the average lat, max/min lat and lons for bounds void avgLatFinder(); // change the features from latlon to xy void convertFeaturesLatLon(); // finds whether to turn left right or go straight (-1, 1, 0) respectively int findLeftorRight(StreetSegmentInfo curr, StreetSegmentInfo next); // clears all global variables before loading a new region void clearMemory(); // populates path vector void populatePath(std::vector<StreetSegmentIdx> &path, IntersectionIdx head, IntersectionIdx tail); // clears node vector void clearNodes();