StudentLifeMap / mapTools.h
mapTools.h
Raw
#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();