Skip to content

Commit

Permalink
the first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
swwelch committed Feb 14, 2019
0 parents commit 4c85819
Show file tree
Hide file tree
Showing 46 changed files with 53,706 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.swp
*.osm
*.o
draw.cpp
test.cpp
build/
bin/
lib/
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "thirdparty/pugixml"]
path = thirdparty/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "thirdparty/googletest"]
path = thirdparty/googletest
url = https://github.com/abseil/googletest.git
39 changes: 39 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.0.0)

if(NOT TESTING)
set(TESTING "notest")
endif()

message("TESTING = ${TESTING}")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

# Use the CMakeLists.txt's parent-directory-name for the project's id/name
get_filename_component(PROJECT_ID ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" PROJECT_ID ${PROJECT_ID})
project(${PROJECT_ID})

#
# Project Output Paths
#
set(MAINFOLDER ${PROJECT_SOURCE_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${MAINFOLDER}/bin")
set(LIBRARY_OUTPUT_PATH "${MAINFOLDER}/lib")

#
# Locate Project Prerequisites
#
find_package(io2d REQUIRED)
find_package(Cairo)
find_package(GraphicsMagick)

#
# Add Build Targets
#
set(IO2D_WITHOUT_SAMPLES 1)
set(IO2D_WITHOUT_TESTS 1)
add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(thirdparty/pugixml)
add_subdirectory(thirdparty/googletest)
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Route Planning Project Starter Code

This is the starter code for the Route Planning project. Instructions for each exercise can be found in the `instructions` directory, and unit tests for some exercises in the `test` directory.

## Compiling and Running

### Compiling
To compile the project, first, create a `build` directory and change to that directory:
```
mkdir build && cd build
```
From within the `build` directory, then run `cmake` and `make` as follows:
```
cmake ..
make
```
### Running
The executables will be placed in the `bin` directory. From within `build`, you can run the project as follows:
```
../bin/<name-of-parent-directory> -f ../map.osm
```

## Testing

For exercises that have unit tests, the project must be built with the approprate test cpp file. This can be done by passing a string with the `-DTESTING` flag in `cmake`. For example, from the build directory:
```
cmake -DTESTING="RouteModel" ..
make
```
Those commands will build the code with the tests for the "Fill Out Route Model" exercise. The tests can then be run from the `build` directory as follows:
```
../bin/test
```
Exercises with tests will specify which string to pass with `-DTESTING`, but a table is given below with the complete list for reference:

| Exercise Name | `-DTESTING` String Value |
|-----------------------------|:------------------------:|
| Fill Out Route Model | "RouteModel" |
| Fill Out Node Class | "RMNodeClass" |
| Create RouteModel Nodes | "RMSNodes" |
| Write the Distance Function | "NodeDist" |
| Create Road to Node Hashmap | "NodeToRoad" |
| Write FindNeighbors | "FindNeighbors" |
| Find the Closest Node | "FindClosest" |
| Write the A\* Search Stub | "AStarStub" |
| Finish A\* Search | "AStarSearch" |

156 changes: 156 additions & 0 deletions cmake/FindCairo.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# - Try to find Cairo
# Once done, this will define
#
# CAIRO_FOUND - system has Cairo
# CAIRO_INCLUDE_DIRS - the Cairo include directories
# CAIRO_LIBRARIES - link these to use Cairo
#
# Copyright (C) 2012 Raphael Kubo da Costa <[email protected]>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

find_package(PkgConfig)
pkg_check_modules(PC_CAIRO QUIET cairo)

find_path(CAIRO_INCLUDE_DIRS
NAMES cairo.h
HINTS ${PC_CAIRO_INCLUDEDIR}
${PC_CAIRO_INCLUDE_DIRS}
PATH_SUFFIXES cairo
)

find_library(CAIRO_LIBRARIES
NAMES cairo
HINTS ${PC_CAIRO_LIBDIR}
${PC_CAIRO_LIBRARY_DIRS}
)
find_library(CAIRO_LIBRARIES_DEBUG
NAMES cairod
HINTS ${PC_CAIRO_LIBDIR}
${PC_CAIRO_LIBRARY_DIRS}
)

if (CAIRO_INCLUDE_DIRS)
set(_CAIRO_PATH ${CAIRO_INCLUDE_DIRS})
while(TRUE)
get_filename_component(_CAIRO_PATH_PART ${_CAIRO_PATH} NAME)
string(TOLOWER ${_CAIRO_PATH_PART} _CAIRO_PATH_PART)
if (${_CAIRO_PATH_PART} STREQUAL "cairo" OR ${_CAIRO_PATH_PART} STREQUAL "include")
get_filename_component(_CAIRO_PATH ${_CAIRO_PATH} DIRECTORY)
continue()
endif()
if (NOT (${_CAIRO_PATH} STREQUAL ""))
set(CAIRO_PATH ${_CAIRO_PATH})
set(CAIRO_PATH ${CAIRO_PATH} PARENT_SCOPE)
endif()
break()
endwhile()
endif()

find_file(CAIRO_DLL
NAMES cairo.dll
HINTS ${CAIRO_PATH}
PATH_SUFFIXES bin
)
find_file(CAIRO_DLL_DEBUG
NAMES cairod.dll
HINTS ${CAIRO_PATH}
PATH_SUFFIXES debug/bin
)

if (CAIRO_INCLUDE_DIRS)
if (EXISTS "${CAIRO_INCLUDE_DIRS}/cairo-version.h")
file(READ "${CAIRO_INCLUDE_DIRS}/cairo-version.h" CAIRO_VERSION_CONTENT)

string(REGEX MATCH "#define +CAIRO_VERSION_MAJOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}")
set(CAIRO_VERSION_MAJOR "${CMAKE_MATCH_1}")

string(REGEX MATCH "#define +CAIRO_VERSION_MINOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}")
set(CAIRO_VERSION_MINOR "${CMAKE_MATCH_1}")

string(REGEX MATCH "#define +CAIRO_VERSION_MICRO +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}")
set(CAIRO_VERSION_MICRO "${CMAKE_MATCH_1}")

set(CAIRO_VERSION "${CAIRO_VERSION_MAJOR}.${CAIRO_VERSION_MINOR}.${CAIRO_VERSION_MICRO}")
endif ()
endif ()

if ("${Cairo_FIND_VERSION}" VERSION_GREATER "${CAIRO_VERSION}")
message(FATAL_ERROR "Required version (" ${Cairo_FIND_VERSION} ") is higher than found version (" ${CAIRO_VERSION} ")")
endif ()

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cairo REQUIRED_VARS CAIRO_INCLUDE_DIRS CAIRO_LIBRARIES
VERSION_VAR CAIRO_VERSION)

mark_as_advanced(
CAIRO_INCLUDE_DIRS
CAIRO_LIBRARIES
CAIRO_LIBRARIES_DEBUG
)

# Create CMake targets
if (CAIRO_FOUND AND NOT TARGET Cairo::Cairo)
if (CAIRO_DLL)
# Not using 'SHARED' when Cairo is available through a .dll can
# cause build issues with MSVC, at least when trying to link against
# a vcpkg-provided copy of "cairod".
add_library(Cairo::Cairo SHARED IMPORTED)
else()
add_library(Cairo::Cairo UNKNOWN IMPORTED)
endif()

set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
INTERFACE_INCLUDE_DIRECTORIES ${CAIRO_INCLUDE_DIRS}
)

if(CAIRO_DLL)
# When using a .dll, the location of *both( the .dll file, and its .lib,
# needs to be specified to CMake. The path to the .dll goes into
# IMPORTED_LOCATION(_*), whereas the path to the .lib goes into
# IMPORTED_IMPLIB(_*).
set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_LOCATION ${CAIRO_DLL}
IMPORTED_IMPLIB ${CAIRO_LIBRARIES}
)
if (CAIRO_DLL_DEBUG)
set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_LOCATION_DEBUG ${CAIRO_DLL_DEBUG}
)
endif()
if (CAIRO_LIBRARIES_DEBUG)
set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_IMPLIB_DEBUG ${CAIRO_LIBRARIES_DEBUG}
)
endif()
else()
set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_LOCATION ${CAIRO_LIBRARIES}
)
if (CAIRO_LIBRARIES_DEBUG)
set_target_properties(Cairo::Cairo PROPERTIES
IMPORTED_LOCATION_DEBUG ${CAIRO_LIBRARIES_DEBUG}
)
endif()
endif()
endif()
89 changes: 89 additions & 0 deletions cmake/FindGraphicsMagick.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#
# FindGraphicsMagick.cmake
#
# When done, if GraphicsMagick is found, the following will be defined:
#
# Library Targets:
# - GraphicsMagick::GraphicsMagick
#
# Global Variables:
# - GRAPHICSMAGICK_FOUND
#

# Use pkg-config, if available, to help find the library
find_package(PkgConfig)
pkg_check_modules(PC_GRAPHICSMAGICK GraphicsMagick)

# Find the header(s)
find_path(GRAPHICSMAGICK_INCLUDE_DIRS
NAMES magick/api.h
HINTS ${PC_GRAPHICSMAGICK_INCLUDE_DIRS}
)

# Find the pre-compiled binary. For Windows + MSVC, this will be its .lib file.
find_library(GRAPHICSMAGICK_LIBRARIES
GraphicsMagick
HINTS ${PC_GRAPHICSMAGICK_LIBRARY_DIRS}
)

# Search for base path of installation
if (GRAPHICSMAGICK_INCLUDE_DIRS)
set(_TMP_PATH ${GRAPHICSMAGICK_INCLUDE_DIRS})
while(TRUE)
get_filename_component(_TMP_PATH_PART ${_TMP_PATH} NAME)
string(TOLOWER ${_TMP_PATH_PART} _TMP_PATH_PART)
if (${_TMP_PATH_PART} STREQUAL "graphicsmagick" OR ${_TMP_PATH_PART} STREQUAL "include")
get_filename_component(_TMP_PATH ${_TMP_PATH} DIRECTORY)
continue()
endif()
if (NOT (${_TMP_PATH} STREQUAL ""))
set(GRAPHICSMAGICK_PATH ${_TMP_PATH})
endif()
break()
endwhile()
endif()

# Look for a pre-compiled .dll file
find_path(GRAPHICSMAGICK_DLL
NAMES graphicsmagick.dll
HINTS ${GRAPHICSMAGICK_PATH}
PATH_SUFFIXES bin
)

# Perform CMake Find-module stuff
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GraphicsMagick
REQUIRED_VARS GRAPHICSMAGICK_INCLUDE_DIRS GRAPHICSMAGICK_LIBRARIES
)

# Create a library target
if (GRAPHICSMAGICK_FOUND AND NOT TARGET GraphicsMagick::GraphicsMagick)
if (GRAPHICSMAGICK_DLL)
# Not using 'SHARED' when Cairo is available through a .dll can
# cause build issues with MSVC, at least when trying to link against
# a vcpkg-provided copy of "cairod".
add_library(GraphicsMagick::GraphicsMagick SHARED IMPORTED)
else()
add_library(GraphicsMagick::GraphicsMagick UNKNOWN IMPORTED)
endif()

set_target_properties(GraphicsMagick::GraphicsMagick PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
INTERFACE_INCLUDE_DIRECTORIES ${GRAPHICSMAGICK_INCLUDE_DIRS}
)

if (GRAPHICSMAGICK_DLL)
# When using a .dll, the location of *both* the .dll file, and its
# .lib, needs to be specified to CMake. The path to the .dll goes
# into IMPORTED_LOCATION(_*), whereas the path to the .lib goes
# into IMPORTED_IMPLIB(_*).
set_target_properties(GraphicsMagick::GraphicsMagick PROPERTIES
IMPORTED_LOCATION ${GRAPHICSMAGICK_DLL}
IMPORTED_IMPLIB ${GRAPHICSMAGICK_LIBRARIES}
)
else()
set_target_properties(GraphicsMagick::GraphicsMagick PROPERTIES
IMPORTED_LOCATION ${GRAPHICSMAGICK_LIBRARIES}
)
endif()
endif()
1 change: 1 addition & 0 deletions instructions/add_user_input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In this exercise, modify `main.cpp` to get floats `start_x`, `start_y`, `end_x`, and `end_y` from the user and pass the inputs to the `RoutePlanner`. Each of these inputs should be in the range 0 to 100.
23 changes: 23 additions & 0 deletions instructions/complete_AStarSearch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
In this exercise, you will complete `AStarSearch()` in `route_planner.cpp` using the `NextNode`, `ConstructFinalPath`, and `AddNeighbors` methods you have written previously.

To complete this exercise:
1. Delete the current contents of `AStarSearch`.
2. Use the `NextNode`, `ConstructFinalPath` and `AddNeighbors` methods to implement the pseudocode below in `AStarSearch`:

>AStarSearch:
>
>1. Set `start_node->visited` to be `true`.
>
>2. Push `start_node` to the back of `open_list`.
>
>3. Create a pointer `RouteModel::Node *current_node` and initialize the pointer to `nullptr`.
>
>4. **while** the `open_list` size is greater than 0:
>
> 1. Set the `current_node` pointer to the results of calling `NextNode`.
> 2. **if** the distance from `current_node` to the `end_node` is 0:
- Call `ConstructFinalPath` using `current_node` and set `m_Model.path` with the results.
- Return to exit the A\* search.
>
> 4. **else** call `AddNeighbors` with the `current_node`./CppND-Route-Planning-Solution -f ../map.osm
````
6 changes: 6 additions & 0 deletions instructions/create_RouteModel_Nodes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Now that you have a `RouteModel` class and you have completed the `RouteModel::Node` nested class, you can create `RouteModel` nodes. When the `RouteModel` constructor is called, it calls the `Model` constructor with the open street map data. When this happens, a collection of `Model:Node` objects are created. However, in order to perform the A\* search, you will need to use `RouteModel::Node` objects instead. In this exercise, you will take the vector of `Model:Node` objects and create a vector of `RouteModel::Node` objects from them that will be stored in the `RouteModel`.


To complete this exercise:

- Write a `for` loop with a counter to loop over `this->Nodes()`, which is the list of `Model::Node` objects. For each node, use the `RouteModel::Node` constructor to create a new node with index given by the counter, and push the node to the back of `m_Nodes`.
9 changes: 9 additions & 0 deletions instructions/fill_RoutePlanner_constructor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Now that you have filled out the header of the `RoutePlanner` class, you can finish writing the constructor in `route_planner.cpp`. The constructor takes one `RouteModel` reference and four `floats` as arguments. The `RouteModel` reference should have been assigned to the `m_Model` variable in the previous exercise. In this exercise, the floats should be used to construct the `start_node` and `end_node` of your class. Follow the instructions below to do this.


To complete this exercise:
1. Within the body of the constructor:
1. Scale the `float`s to percentages by multiplying each `float` by 0.01 and storing the result in the float variable. For example: `start_x *= 0.01;`
2. Use the `m_Model.FindClosestNode` method to find the closest nodes to `(start_x, start_y)` and `(end_x, end_y)`. Store pointers to these nodes in the `start_node` and `end_node` class variables.

Note that there are no tests for this exercise. Your code should compile, and this class will be tested in later exercises.
Loading

0 comments on commit 4c85819

Please sign in to comment.