RanCoord is a Python package for random sampling of geographic coordinates!
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Table of Contents
![RanCoord Logo](images/rancoord_logo.png)
This project arises within the scope of research and development activities in the area of freight transport with respect to vehicle routing problems. Geographic coordinates are one of the most accurate means of identifying a location with extreme sensitivity.
Thus, with this project it is intended:
- Reduce the time and effort required to acquire geographic coordinates within a specific location
- Eliminate the need to use geographic data that do not fit a particular problem to be addressed
- Provide geographic coordinates in an extremely easy, fast and customized way to the user's needs
As time goes on, according to my availability and the feedback offered by users it is expected that new features will be included in this package that can make life easier for users addressing vehicle routing problems associated with geographic coordinates. A list of commonly used resources that I find helpful are listed in the acknowledgements.
The major frameworks used to build this project were:
This section presents how the package can be reached and installed.
The source code is currently hosted on GitHub at: https://github.com/hugodscarvalho/rancoord
Binary installer for the latest released version are available at the Python Package Index (PyPI).
pip install rancoord
The first step in using the package is, after it has been installed, to import it.
import rancoord as rc
In order to be able to generate a number of random geographic coordinates within a specific location it is necessary to create the polygon that encompasses it. The package provides three different ways to approach this prerequisite.
If you choose this option, there's no need to define it, the geographic randomizer module will already have it defined. Geographic data comprised in it:
poly = Polygon(
[
(38.78562804689748, -9.47276949903965),
(38.713870245772654, -9.139059782242775),
(38.89740476139506, -9.055975675797463),
(38.96871087768789, -8.969115019059181),
(39.05061092686942, -8.92894625685215),
(39.08579612091302, -9.407538175797463),
(38.984457987516386, -9.397238493180275),
]
)
Map visualization:
![RanCoord Default Location](images/default_location.png)
If you choose this option, you will have to define the polygon using some geographic tool as the app from Headwall Photonics, copy the coordinates, structure them and define de polygon.
If you choose this option, you can get a polygon based on the bounding box of an address or location using Noninatim.
# Get the bounding box
bounding_box = nominatim_geocoder('Braga, Portugal')
# Create a polygon based on the previously created bounding box
poly = polygon_from_boundingbox(bounding_box)
Once the geographic polygon has been defined, the next step is to generate the geographic coordinates. You can also choose to modify the number of locations to generate within the polygon (default is 10). In addition, although by default these options are disabled, you can choose to save the geographic coordinates and to save a map containing them (options explained below).
lat, lon = coordinates_randomizer(polygon = poly, num_locations = 50, plot = True, save = True)
This method will return two lists, one with the latitudes and one with the longitudes with the following characteristics:
- Locations within the previously defined polygon
- 50 locations
- A plot will be saved in the
/maps
folder with the .html format and named by defaultmap_DDMMYYYY_HHMMSS
with the temporal information of locations generation. - A file containing the locations will be saved in the
/coordinates
folder with the default.json
format and named by defaultcoordinates_DDMMYYYY_HHMMSS
with the temporal information of locations generation.
The following methods were used in the development of this random geocraphic coordinates generation.
create_dir
nominatim_geocoder
polygon_from_boundingbox
list_average
plot_coordinates
multiple_formats_saver
haversine_distance
vincenty_distance
osrm_distance
distance_matrix
Auxiliar function to create a new directory if it doesn't already exists. User can choose to name the specific location.
Arguments
dir_name
[String] : Address the new name. Defaults to 'data'.
Example
dir_name = 'example'
create_dir(dir_name)
Function to geocode an address using the Nominatim geocoder and return the bounding box of the address.
Arguments
address
[String] : Address to geocode.
Raises
ValueError
(address): The introduced adress was not found. Please introduce a valid address.
Returns
- [List] : List of coordinates of the bounding box of the address.
Example
bounding_box = nominatim_geocoder(address = 'Barcelona, Spain')
Function to create a polygon from a bounding box.
Arguments
boundingbox
[List] : List of coordinates of the bounding box.
Returns
- [Polygon] : Polygon created from the bounding box.
Example
poly = polygon_from_boundingbox(boundingbox = bounding_box)
Function to calculate the average of a list of numbers in order to center geographical map.
Arguments
list_of_numbers
[List] : List of numbers.
Returns
- [float] : Average of the list of numbers.
Example
avg = list_average(list_of_numbers = [1, 2, 2, 3, 6, 7])
Function to calculate the average of a list of numbers in order to center geographical map.
Arguments
lat
[List] : List of numbers.lon
[List] : List of numbers.zoom
[Integer] : Zoom level of the map. Defaults to 11.save
[Boolean] : If True, the map will be saved. Defaults to True.
Returns
- [Folium Map] : Folium map with the coordinates.
Example
map = plot_coordinates(lat = lat, lon = lon, zoom = 11, save = True)
This function saves the coordinates lat and lon as the names introduced in a given columns list ('Latitude' and 'Longitude' by default). The coordinates are saved in a given format introduced by the user among the possibilities csv, json, txt and xlsx (json by default) and the output file name is also given by the user as file_name. User can choose the directory name where the output file will be saved.
Arguments
lat
[List] : List of latitude values.lon
[List] : List of longitude values.columns
[Integer] : Column names. Defaults to ['Latitude', 'Longitude'].file_format
[String] : File format. Defaults to 'json'.file_name
[String] : File name. Defaults to 'coordinates'.dir_name
[String] : Directory name. Defaults to 'coordinates'.
Raises
AssertionError
(lat): No values found on the latitude list.AssertionError
(lon): No values found on the longitude list.AssertionError
(lat & lon): The lists must have the same length.AssertionError
(columns): No column names found.AssertionError
(columns): The column names list must have two elements.AssertionError
(file_name): No file name found.AssertionError
(dir_name): No directory name found.
Returns
- [None] : None.
Example
multiple_formats_saver(lat = lat, lon = lon, columns = ['Latitude', 'Longitude'], file_format = 'json', file_name = 'coordinates', dir_name = 'coordinates')
The haversine formula is used to calculate the great-circle distance between two points on a sphere given their longitudes and latitudes.
Arguments
pickup_lat
[float] : The latitude of the pickup location.pickup_long
[float] : The longitude of the pickup location.dropoff_lat
[float] : The latitude of the dropoff location.dropoff_long
[float] : The longitude of the dropoff location.miles
[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.
Returns
- [float] : The distance between two points on a sphere.
Example
haversine = haversine_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)
The function takes the latitude and longitude of two points on the Earth's surface and returns the distance between them in kilometers using the Vincenty's formula.
Arguments
pickup_lat
[float] : The latitude of the pickup location.pickup_long
[float] : The longitude of the pickup location.dropoff_lat
[float] : The latitude of the dropoff location.dropoff_long
[float] : The longitude of the dropoff location.miles
[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.
Returns
- [float] : The distance between two points on the earth using the vincenty's formula.
Example
vincenty = vincenty_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)
This function takes in the pickup and dropoff coordinates and returns the distance between them in kilometers by default using the OSRM API.
Arguments
pickup_lat
[float] : The latitude of the pickup location.pickup_long
[float] : The longitude of the pickup location.dropoff_lat
[float] : The latitude of the dropoff location.dropoff_long
[float] : The longitude of the dropoff location.miles
[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.
Returns
- [float] : The distance between two coordinates.
Example
osrm = osrm_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)
For each pair of geographic coordinates, calculate the distance between them using the specified method and return a matrix of distances.
Arguments
lat
[List] : List of latitudes.lon
[List] : List of longitudes.method
[String] : The method to use to calculate the distances. 'haversine', 'vincenty' or 'osrm'. Vincenty's distance by default.
Returns
- [numpy.ndarray] : A matrix of distances between each pair of coordinates.
Example
haversine = haversine_distance(lat = lat, lon = lon, method = 'osrm')
The following examples show an extended full code usage of the package.
![RanCoord Extended Usage](images/extended_usage.png)
Random coordinates:
Distance matrix:
Map visualization:
See the open issues for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.
Project Link: Github Linkedin: hugodscarvalho