{"id":28152660,"url":"https://github.com/hugodscarvalho/rancoord","last_synced_at":"2025-09-07T18:40:59.527Z","repository":{"id":49523526,"uuid":"478344624","full_name":"hugodscarvalho/rancoord","owner":"hugodscarvalho","description":"RanCoord is a Python package for random sampling of geographic coordinates","archived":false,"fork":false,"pushed_at":"2022-07-28T09:37:32.000Z","size":9438,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-13T11:13:36.520Z","etag":null,"topics":["coordinates","distance-matrix","geographic","haversine-distance","osrm","randomizer","vehicle-routing-problem","vincenty"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hugodscarvalho.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-04-06T00:23:31.000Z","updated_at":"2025-03-20T14:09:21.000Z","dependencies_parsed_at":"2022-09-16T19:00:21.108Z","dependency_job_id":null,"html_url":"https://github.com/hugodscarvalho/rancoord","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugodscarvalho%2Francoord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugodscarvalho%2Francoord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugodscarvalho%2Francoord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hugodscarvalho%2Francoord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hugodscarvalho","download_url":"https://codeload.github.com/hugodscarvalho/rancoord/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254276452,"owners_count":22043869,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coordinates","distance-matrix","geographic","haversine-distance","osrm","randomizer","vehicle-routing-problem","vincenty"],"created_at":"2025-05-15T05:11:52.829Z","updated_at":"2025-05-15T05:11:52.895Z","avatar_url":"https://github.com/hugodscarvalho.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n\n\u003c!-- PROJECT SHIELDS --\u003e\n\u003c!--\n*** I'm using markdown \"reference style\" links for readability.\n*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).\n*** See the bottom of this document for the declaration of the reference variables\n*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.\n*** https://www.markdownguide.org/basic-syntax/#reference-style-links\n--\u003e\n\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/rancoord_logo.png\" alt=\"RanCoord Logo\" height=\"200\"\u003e\n  \u003c/a\u003e\n  \u003ch3 align=\"center\"\u003eRanCoord\u003c/h3\u003e\n  \u003cp align=\"center\"\u003e\n    RanCoord is a Python package for random sampling of geographic coordinates!\n    \u003cbr /\u003e\n    \u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003eView Demo\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/hugodscarvalho/rancoord/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/hugodscarvalho/rancoord/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails open=\"open\"\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#about-the-project\"\u003eAbout The Project\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#built-with\"\u003eBuilt With\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n      \u003ca href=\"#getting-started\"\u003eGetting Started\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\u003c/li\u003e\n        \u003cli\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#roadmap\"\u003eRoadmap\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#acknowledgements\"\u003eAcknowledgements\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n## About The Project\n\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/rancoord_logo.png\" alt=\"RanCoord Logo\" height=\"80\"\u003e\n\u003c/a\u003e\n\nThis 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.\n\nThus, with this project it is intended:\n* Reduce the time and effort required to acquire geographic coordinates within a specific location\n* Eliminate the need to use geographic data that do not fit a particular problem to be addressed\n* Provide geographic coordinates in an extremely easy, fast and customized way to the user's needs\n\nAs 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.\nA list of commonly used resources that I find helpful are listed in the acknowledgements.\n\n### Built With\n\nThe major frameworks used to build this project were:\n* [Python](https://www.python.org/)\n* [Folium](https://github.com/python-visualization/folium)\n* [Project OSRM](http://project-osrm.org/)\n\n\n\n\u003c!-- GETTING STARTED --\u003e\n## Getting Started\n\nThis section presents how the package can be reached and installed.\n\n### Where to get it\n\nThe source code is currently hosted on GitHub at: https://github.com/hugodscarvalho/rancoord\n\nBinary installer for the latest released version are available at the Python Package Index (PyPI).\n\n```sh\npip install rancoord\n```\n\n\u003c!-- USAGE EXAMPLES --\u003e\n## Usage\n\n### 1. Import the package\nThe first step in using the package is, after it has been installed, to import it.\n\n```python\nimport rancoord as rc\n```\n\n### 2. Geographical polygon \n\nIn 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.\n\n#### 2.1. Use the default polygon\nIf 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:\n\n```python\npoly = Polygon(\n    [\n        (38.78562804689748, -9.47276949903965),\n        (38.713870245772654, -9.139059782242775),\n        (38.89740476139506, -9.055975675797463),\n        (38.96871087768789, -8.969115019059181),\n        (39.05061092686942, -8.92894625685215),\n        (39.08579612091302, -9.407538175797463),\n        (38.984457987516386, -9.397238493180275),\n    ]\n)\n```\nMap visualization:\n\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/default_location.png\" alt=\"RanCoord Default Location\"\u003e\n\u003c/a\u003e\n\n#### 2.2. Create your own polygon\nIf you choose this option, you will have to define the polygon using some geographic tool as the app from [Headwall Photonics](http://apps.headwallphotonics.com/), copy the coordinates, structure them and define de polygon.\n\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/headwall_photonics.PNG\" alt=\"Headwall Photonics App\"\u003e\n\u003c/a\u003e\n\n#### 2.3. Get a polygon using an address using \nIf you choose this option, you can get a polygon based on the [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box) of an address or location using *Noninatim*. \n```python\n# Get the bounding box\nbounding_box = nominatim_geocoder('Braga, Portugal')\n# Create a polygon based on the previously created bounding box\npoly = polygon_from_boundingbox(bounding_box)\n```\n\n### 3. Randomize the geographic coordinates\nOnce 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*).\n\n```python\nlat, lon = coordinates_randomizer(polygon = poly, num_locations = 50, plot = True, save = True)\n```\n\nThis method will return two lists, one with the latitudes and one with the longitudes with the following characteristics:\n1. Locations within the previously defined polygon\n2. 50 locations\n3. A plot will be saved in the `/maps` folder with the .html format and named by default `map_DDMMYYYY_HHMMSS` with the temporal information of locations generation.\n4. A file containing the locations will be saved in the `/coordinates` folder with the default `.json` format and named by default `coordinates_DDMMYYYY_HHMMSS` with the temporal information of locations generation.\n\n### 4. [EXTRA] Auxiliar methods\nThe following methods were used in the development of this random geocraphic coordinates generation.\n\n* [`create_dir`](#create_dir)\n* [`nominatim_geocoder`](#nominatim_geocoder)\n* [`polygon_from_boundingbox`](#polygon_from_boundingbox)\n* [`list_average`](#list_average)\n* [`plot_coordinates`](#plot_coordinates)\n* [`multiple_formats_saver`](#multiple_formats_saver)\n* [`haversine_distance`](#haversine_distance)\n* [`vincenty_distance`](#vincenty_distance)\n* [`osrm_distance`](#osrm_distance)\n* [`distance_matrix`](#distance_matrix)\n\n\n\u003ca name=\"create_dir\"/\u003e\n\n#### create_dir( dir_name )\n\nAuxiliar function to create **a new directory** if it doesn't already exists. User can choose to name the specific location.\n\n___Arguments___\n* `dir_name` [String] : Address the new name. **Defaults** to *'data'*.                                                                                        \n\n___Example___\n\n```python\ndir_name = 'example'\n\ncreate_dir(dir_name)\n```\n\n-------------------------------------------\n\n\u003ca name=\"nominatim_geocoder\"/\u003e\n\n#### nominatim_geocoder(address)\n\nFunction to geocode an address using the Nominatim geocoder and return the bounding box of the address.\n\n___Arguments___\n* `address` [String] :  Address to geocode.\n\n___Raises___\n* `ValueError` **(address)**: The introduced adress was not found. Please introduce a valid address.\n\n___Returns___\n* [List] : List of coordinates of the bounding box of the address.\n\n___Example___\n\n```python\n\nbounding_box = nominatim_geocoder(address = 'Barcelona, Spain')\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"polygon_from_boundingbox\"/\u003e\n\n#### polygon_from_boundingbox(boundingbox)\n\nFunction to create a polygon from a bounding box.\n\n___Arguments___\n* `boundingbox` [List] : List of coordinates of the bounding box.\n\n___Returns___\n* [Polygon] : Polygon created from the bounding box.\n\n___Example___\n\n```python\n\npoly = polygon_from_boundingbox(boundingbox = bounding_box)\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"list_average\"/\u003e\n\n#### list_average(list_of_numbers)\n\nFunction to calculate the average of a list of numbers in order to center geographical map.\n\n___Arguments___\n* `list_of_numbers` [List] : List of numbers.\n\n___Returns___\n* [float] : Average of the list of numbers.\n\n___Example___\n\n```python\n\navg = list_average(list_of_numbers = [1, 2, 2, 3, 6, 7])\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"plot_coordinates\"/\u003e\n\n#### plot_coordinates(list_of_numbers)\n\nFunction to calculate the average of a list of numbers in order to center geographical map.\n\n___Arguments___\n* `lat` [List] : List of numbers.\n* `lon` [List] : List of numbers.\n* `zoom` [Integer] :  Zoom level of the map. Defaults to 11.\n* `save`[Boolean] : If True, the map will be saved. Defaults to True.\n\n\n___Returns___\n* [Folium Map] : Folium map with the coordinates.\n\n___Example___\n\n```python\n\nmap = plot_coordinates(lat = lat, lon = lon, zoom = 11, save = True)\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"multiple_formats_saver\"/\u003e\n\n#### multiple_formats_saver(lat, lon, columns, file_format, file_name, dir_name)\n\nThis function saves the coordinates lat and lon as the names introduced\nin a given columns list ('Latitude' and 'Longitude' by default). The\ncoordinates are saved in a given format introduced by the user among the\npossibilities csv, json, txt and xlsx (json by default) and the output\nfile name is also given by the user as file_name. User can choose the\ndirectory name where the output file will be saved.\n\n___Arguments___\n* `lat` [List] : List of latitude values.\n* `lon` [List] : List of longitude values.\n* `columns` [Integer] :  Column names. Defaults to ['Latitude', 'Longitude'].\n* `file_format`[String] : File format. Defaults to 'json'.\n* `file_name`[String] : File name. Defaults to 'coordinates'.\n* `dir_name`[String] : Directory name. Defaults to 'coordinates'.\n\n___Raises___\n* `AssertionError` **(lat)**: No values found on the latitude list.\n* `AssertionError` **(lon)**: No values found on the longitude list.\n* `AssertionError` **(lat \u0026 lon)**: The lists must have the same length.\n* `AssertionError` **(columns)**: No column names found.\n* `AssertionError` **(columns)**: The column names list must have two elements. \n* `AssertionError` **(file_name)**: No file name found.\n* `AssertionError` **(dir_name)**: No directory name found.\n\n___Returns___\n* [None] : None.\n\n___Example___\n\n```python\n\nmultiple_formats_saver(lat = lat, lon = lon, columns = ['Latitude', 'Longitude'], file_format = 'json', file_name = 'coordinates', dir_name = 'coordinates')\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"haversine_distance\"/\u003e\n\n#### haversine_distance(pickup_lat, pickup_long, dropoff_lat, dropoff_long, miles)\n\nThe haversine formula is used to calculate the great-circle distance between two points on a sphere given their longitudes and latitudes.\n\n___Arguments___\n* `pickup_lat` [float] : The latitude of the pickup location.\n* `pickup_long` [float] : The longitude of the pickup location.\n* `dropoff_lat` [float] :  The latitude of the dropoff location.\n* `dropoff_long` [float] :  The longitude of the dropoff location.\n* `miles`[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.\n\n\n___Returns___\n* [float] : The distance between two points on a sphere.\n\n___Example___\n\n```python\n\nhaversine = haversine_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"vincenty_distance\"/\u003e\n\n#### vincenty_distance(pickup_lat, pickup_long, dropoff_lat, dropoff_long, miles)\n\nThe 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.\n\n___Arguments___\n* `pickup_lat` [float] : The latitude of the pickup location.\n* `pickup_long` [float] : The longitude of the pickup location.\n* `dropoff_lat` [float] :  The latitude of the dropoff location.\n* `dropoff_long` [float] :  The longitude of the dropoff location.\n* `miles`[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.\n\n\n___Returns___\n* [float] : The distance between two points on the earth using the vincenty's formula.\n\n___Example___\n\n```python\n\nvincenty = vincenty_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"osrm_distance\"/\u003e\n\n#### osrm_distance(pickup_lat, pickup_long, dropoff_lat, dropoff_long, miles)\n\nThis function takes in the pickup and dropoff coordinates and returns the distance between them in kilometers by default using the OSRM API.\n\n___Arguments___\n* `pickup_lat` [float] : The latitude of the pickup location.\n* `pickup_long` [float] : The longitude of the pickup location.\n* `dropoff_lat` [float] :  The latitude of the dropoff location.\n* `dropoff_long` [float] :  The longitude of the dropoff location.\n* `miles`[Boolean] : If True, the output will be in miles. If False, the output will be in kilometers. Defaults to False.\n\n\n___Returns___\n* [float] : The distance between two coordinates.\n\n___Example___\n\n```python\n\nosrm = osrm_distance(pickup_lat = 41.4781, pickup_long = -8.1992 , dropoff_lat = 40.8761 , dropoff_long = -9.1222, miles = False)\n\n```\n\n-------------------------------------------\n\n\u003ca name=\"distance_matrix\"/\u003e\n\n#### distance_matrix(lat, lon, method)\n\nFor each pair of geographic coordinates, calculate the distance between them using the specified method and return a matrix of distances.\n\n___Arguments___\n* `lat` [List] :  List of latitudes.\n* `lon` [List] : List of longitudes.\n* `method` [String] :  The method to use to calculate the distances. 'haversine', 'vincenty' or 'osrm'. Vincenty's distance by default.\n\n___Returns___\n* [numpy.ndarray] : A matrix of distances between each pair of coordinates.\n\n___Example___\n\n```python\n\nhaversine = haversine_distance(lat = lat, lon = lon, method = 'osrm')\n\n```\n\n-------------------------------------------\n\n### 5. [EXTENDED] Full code usage\nThe following examples show an extended full code usage of the package.\n\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/extended_usage.png\" alt=\"RanCoord Extended Usage\"\u003e\n\u003c/a\u003e\n\nRandom coordinates:\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/random_coordinates.png\" alt=\"RanCoord Random Coordinates\" width=\"500\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\nDistance matrix:\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/distance_matrix.png\" alt=\"RanCoord Distance Matrix\" width=\"500\"\u003e \n\u003c/a\u003e\n\u003c/p\u003e\n\nMap visualization:\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/hugodscarvalho/rancoord\"\u003e\n    \u003cimg src=\"images/folium_map.png\" alt=\"RanCoord Folium Map\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\n\u003c!-- ROADMAP --\u003e\n## Roadmap\n\nSee the [open issues](https://github.com/hugodscarvalho/rancoord/issues) for a list of proposed features (and known issues).\n\n\n\n\u003c!-- CONTRIBUTING --\u003e\n## Contributing\n\nContributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n\n\n\u003c!-- LICENSE --\u003e\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.\n\n\n\n\u003c!-- CONTACT --\u003e\n## Contact\n\nProject Link: [Github](https://github.com/hugodscarvalho/rancoord)\nLinkedin: [hugodscarvalho](https://www.linkedin.com/in/hugodscarvalho)\n\n\n\n\u003c!-- ACKNOWLEDGEMENTS --\u003e\n## Acknowledgements\n* [Folium](https://github.com/python-visualization/folium)\n* [Project OSRM](http://project-osrm.org/)\n* [Geopy](https://github.com/geopy/geopy)\n\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --\u003e\n[license-url]: https://github.com/hugodscarvalho/rancoord/blob/main/LICENSE\n[linkedin-url]: https://linkedin.com/in/hugodscarvalho\n[product-screenshot]: images/rancoord_logo.png\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugodscarvalho%2Francoord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhugodscarvalho%2Francoord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhugodscarvalho%2Francoord/lists"}