├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── docs ├── directions.md ├── geocoding.md ├── isochrone.md ├── mapmatching.md ├── matrix.md ├── optimization.md └── tilequery.md ├── lib ├── mapbox-sdk.rb ├── mapbox.rb └── mapbox │ ├── api_operations.rb │ ├── authentication_error.rb │ ├── directions.rb │ ├── geocoder.rb │ ├── isochrone.rb │ ├── map_matching.rb │ ├── matrix.rb │ ├── optimization.rb │ └── tilequery.rb ├── mapbox-sdk.gemspec └── test ├── all_tests.rb ├── directions_test.rb ├── geocoding_test.rb ├── isochrone_test.rb ├── map_matching_test.rb ├── mapbox_test.rb ├── matrix_test.rb ├── optimization_test.rb └── tilequery_test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.5.1 4 | install: 5 | - bundle install 6 | script: 7 | - bundle exec ruby -Itest test/all_tests.rb 8 | after_success: 9 | - coveralls -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [2.3.3] - 2021-09-08 8 | ### Changed 9 | - See https://github.com/mapbox/mapbox-sdk-rb/pull/55 / https://github.com/mapbox/mapbox-sdk-rb/issues/54 10 | 11 | ## [2.3.2] - 2020-11-23 12 | ### Changed 13 | - Fixed URI.encode obsolete warnings in Ruby 2.7 14 | 15 | ## [2.3.1] - 2020-11-07 16 | ### Changed 17 | - Update to restclient 2.1.0 18 | 19 | ## [2.3.0] - 2019-01-16 20 | ### Added 21 | - Matrix endpoint, docs, and tests 22 | - Map Matching endpoint, docs, and tests 23 | - Optimization endpoint, docs, and tests 24 | 25 | ### Changed 26 | 27 | ### Removed 28 | 29 | ## [2.2.0] - 2018-12-14 30 | ### Added 31 | - Selection of directions profiles 32 | - Isochrone endpoint 33 | - New README/docs folder and organization 34 | 35 | ### Changed 36 | - Update to restclient 2.0 37 | - Parameters to requests for directions 38 | 39 | ### Removed 40 | 41 | ## [2.1.0] - 2018-06-07 42 | ### Added 43 | - Added CHANGELOG.md 44 | - Added Tilequery endpoint 45 | 46 | ### Changed 47 | - Updated documentation links in README 48 | 49 | ### Removed 50 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gemspec 3 | 4 | if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('1.9.3') 5 | gem 'i18n', '< 0.7' 6 | gem 'rest-client', '~> 2.1.0' 7 | gem "activesupport", ">= 4.1.11" 8 | gem 'rake', '10.1.0' 9 | end 10 | 11 | group :development, :test do 12 | gem "coveralls", :require => false 13 | end 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Mapbox 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | --- 16 | 17 | The MIT License 18 | 19 | Copyright (c) 2011- Stripe, Inc. (https://stripe.com) 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in 29 | all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 | THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-sdk-rb/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-sdk-rb?branch=master) 2 | 3 | # mapbox-sdk-ruby 4 | 5 | The `mapbox-sdk` gem. A ruby interface to [Mapbox APIs](https://www.mapbox.com/developers/api/). 6 | 7 | ## Installation 8 | 9 | ``` 10 | gem install mapbox-sdk 11 | ``` 12 | 13 | ## Services 14 | 15 | * [Geocoding](https://docs.mapbox.com/api/search/) [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/geocoding.md)] 16 | * Forward (place names ⇢ longitude, latitude) 17 | * Reverse (longitude, latitude ⇢ place names) 18 | * [Directions](https://docs.mapbox.com/api/navigation/#directions): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/directions.md)] 19 | * Profiles for driving, driving-traffic, walking, and cycling 20 | * [Tilequery](https://docs.mapbox.com/api/maps/#tilequery): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/tilequery.md)] 21 | * [Isochrone](https://docs.mapbox.com/api/navigation/#isochrone): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/isochrone.md)] 22 | * Profiles for driving, walking, and cycling 23 | * [Matrix](https://docs.mapbox.com/api/navigation/#matrix): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/matrix.md)] 24 | * Profiles for driving, driving-traffic, walking, and cycling 25 | * [Map Matching](https://docs.mapbox.com/api/navigation/#map-matching): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/mapmatching.md)] 26 | * Profiles for driving, driving-traffic, walking, and cycling 27 | * [Optimization](https://docs.mapbox.com/api/navigation/#optimization): [[docs](https://github.com/mapbox/mapbox-sdk-rb/blob/master/docs/optimization.md)] 28 | * Profiles for driving, driving-traffic, walking, and cycling 29 | 30 | ## Testing 31 | 32 | You'll need to [create an access token](https://account.mapbox.com/access-tokens/create) in order to run tests. 33 | 34 | Then you can run the entire test suite with the following command: 35 | 36 | ``` 37 | MapboxAccessToken= bundle exec ruby -Itest test/all_tests.rb 38 | ``` 39 | 40 | Heavily influenced by Stripe's Ruby client, and includes its MIT license. 41 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/testtask' 2 | 3 | task :default => [:test] 4 | 5 | Rake::TestTask.new do |t| 6 | t.pattern = './test/**/*_test.rb' 7 | end 8 | -------------------------------------------------------------------------------- /docs/directions.md: -------------------------------------------------------------------------------- 1 | # Directions 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | # Driving directions with required profile parameter. 8 | drivingDirections = Mapbox::Directions.directions([{ 9 | "longitude" => -100, 10 | "latitude" => 38 11 | }, { 12 | "longitude" => -90, 13 | "latitude" => 38 14 | }], "driving") 15 | 16 | # To provide query parameters to the Directions API, such as `geometries`, `language` or `steps`, add those in a Hash as third parameter (find the full list of parameters (here)[https://www.mapbox.com/api-documentation/navigation/#retrieve-directions]). 17 | 18 | # For instance, to use the `geometries` and `voice_instructions` parameter: 19 | drivingDirections = Mapbox::Directions.directions([{ 20 | "longitude" => -100, 21 | "latitude" => 38 22 | }, { 23 | "longitude" => -90, 24 | "latitude" => 38 25 | }], "driving", { 26 | geometries: "geojson", 27 | voice_instructions: true 28 | }) 29 | 30 | # In the above example, you can substitute `driving` for `driving-traffic`, `cycling` or `walking`. For more, [check out the documentation](https://www.mapbox.com/api-documentation/navigation/#directions). 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/geocoding.md: -------------------------------------------------------------------------------- 1 | # Geocoding 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | # Reverse geocoding 8 | placenames = Mapbox::Geocoder.geocode_reverse({ 9 | "latitude": 38, 10 | "longitude": -100 11 | }) 12 | 13 | # Forward geocoding with optional proximity parameter 14 | places = Mapbox::Geocoder.geocode_forward("Chester, NJ", {:proximity => {:longitude => -74.6968, :latitude => 40.7843}}) 15 | ``` -------------------------------------------------------------------------------- /docs/isochrone.md: -------------------------------------------------------------------------------- 1 | # Isochrone 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | isochrone = Mapbox::Isochrone.isochrone("walking", "-118.22258,33.99038", {contours_minutes: [5,10,15]}) 8 | 9 | # You must include the contours_minutes parameter, as well as a profile (walking, driving, cycling) and the center point coordinate. 10 | # Optional parameters are contours_colors, polygons, denoise, and generalize. See more on the API documentation page. 11 | ``` -------------------------------------------------------------------------------- /docs/mapmatching.md: -------------------------------------------------------------------------------- 1 | # Map Matching 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | # Snap fuzzy, inaccurate GPS or phone traces to the road and path network with required profile parameter. 8 | matching = Mapbox::MapMatching.map_matching([{ 9 | "longitude" => -117.17282, 10 | "latitude" => 32.71204 11 | }, { 12 | "longitude" => -117.17288, 13 | "latitude" => 32.71225 14 | }, { 15 | "longitude" => -117.17293, 16 | "latitude" => 32.71244 17 | },{ 18 | "longitude" => -117.17292, 19 | "latitude" => 32.71256 20 | }], "driving") 21 | 22 | # To provide query parameters to the Matrix API, such as `annotations`, `approaches` or `sources`, add those in a Hash as third parameter (find the full list of parameters (here)[https://www.mapbox.com/api-documentation/navigation/#matrix]). 23 | 24 | # For instance, to use the `geometries` and `voice_instructions` parameter: 25 | matching = Mapbox::MapMatching.map_matching([{ 26 | "longitude" => -117.17282, 27 | "latitude" => 32.71204 28 | }, { 29 | "longitude" => -117.17288, 30 | "latitude" => 32.71225 31 | }, { 32 | "longitude" => -117.17293, 33 | "latitude" => 32.71244 34 | },{ 35 | "longitude" => -117.17292, 36 | "latitude" => 32.71256 37 | }], "driving", { 38 | annotations: ["duration", "distance", "speed"], 39 | approaches: ["curb","curb","curb","curb"] 40 | }) 41 | 42 | # In the above example, you can substitute `driving` for `driving-traffic`, `cycling` or `walking`. For more, [check out the documentation](https://docs.mapbox.com/api/navigation/#map-matching). 43 | ``` -------------------------------------------------------------------------------- /docs/matrix.md: -------------------------------------------------------------------------------- 1 | # Matrix 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | # Return travel times between many points, passing in the required profile parameter. 8 | matrix = Mapbox::Matrix.matrix([{ 9 | "longitude" => -122.42, 10 | "latitude" => 37.78 11 | }, { 12 | "longitude" => -122.45, 13 | "latitude" => 37.91 14 | }, { 15 | "longitude" => -122.48, 16 | "latitude" => 37.73 17 | }], "walking") 18 | 19 | # To provide query parameters to the Matrix API, such as `annotations`, `approaches` or `sources`, add those in a Hash as third parameter (find the full list of parameters (here)[https://www.mapbox.com/api-documentation/navigation/#matrix]). 20 | 21 | # For instance, to use the `annotations`, `approaches`, and `destinations` parameters: 22 | matrix = Mapbox::Matrix.matrix([{ 23 | "longitude" => -122.42, 24 | "latitude" => 37.78 25 | }, { 26 | "longitude" => -122.45, 27 | "latitude" => 37.91 28 | }, { 29 | "longitude" => -122.48, 30 | "latitude" => 37.73 31 | }], "cycling", { 32 | annotations: ["duration", "distance"], 33 | approaches: ["curb","","curb"], 34 | destinations: [0,1] 35 | }) 36 | 37 | # In the above example, you can substitute `driving` for `driving-traffic`, `cycling` or `walking`. For more, [check out the documentation](https://www.mapbox.com/api-documentation/navigation/#matrix). 38 | ``` -------------------------------------------------------------------------------- /docs/optimization.md: -------------------------------------------------------------------------------- 1 | # Optimization 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | # Returns a duration-optimized route between coordinates with required profile parameter. 8 | optimization = Mapbox::Optimization.optimization([{ 9 | "longitude" => -122.42, 10 | "latitude" => 37.78 11 | }, { 12 | "longitude" => -122.45, 13 | "latitude" => 37.91 14 | }, { 15 | "longitude" => -122.48, 16 | "latitude" => 37.73 17 | }], "walking") 18 | 19 | # To provide query parameters to the Matrix API, such as `annotations`, `approaches` or `sources`, add those in a Hash as third parameter (find the full list of parameters (here)[https://www.mapbox.com/api-documentation/navigation/#matrix]). 20 | 21 | # For instance, to use the `annotations`, `approaches`, and `overview` parameters: 22 | optimization = Mapbox::Optimization.optimization([{ 23 | "longitude" => -122.42, 24 | "latitude" => 37.78 25 | }, { 26 | "longitude" => -122.45, 27 | "latitude" => 37.91 28 | }, { 29 | "longitude" => -122.48, 30 | "latitude" => 37.73 31 | }], "cycling", { 32 | annotations: ["duration", "distance"], 33 | approaches: ["curb","curb","curb"], 34 | overview: "false" 35 | }) 36 | 37 | # The bearings param works a bit differently. Here's an example, leaving the second bearing blank with an additional `;` character (you must include the same number of bearings as waypoints, per the docs): 38 | optimization = Mapbox::Optimization.optimization([{ 39 | "longitude" => -122.42, 40 | "latitude" => 37.78 41 | }, { 42 | "longitude" => -122.45, 43 | "latitude" => 37.91 44 | }, { 45 | "longitude" => -122.48, 46 | "latitude" => 37.73 47 | }], "driving", { 48 | bearings: "45,90;;90,1" 49 | }) 50 | 51 | # In the above example, you can substitute `driving` for `driving-traffic`, `cycling` or `walking`. For more, [check out the documentation](https://docs.mapbox.com/api/navigation/#optimization). 52 | ``` -------------------------------------------------------------------------------- /docs/tilequery.md: -------------------------------------------------------------------------------- 1 | # Tilequery 2 | 3 | ```rb 4 | require "mapbox-sdk" 5 | Mapbox.access_token = "YOUR_ACCESS_TOKEN" 6 | 7 | tilequery = Mapbox::Tilequery.tilequery(mapid, {location}, radius, limit) 8 | 9 | # Example: tilequery = Mapbox::Tilequery.tilequery("mapbox.mapbox-streets-v7", {"longitude" => -100, "latitude" => 38}, 0, 1) 10 | # `Radius` refers to the approximate distance in meters to query for features. Defaults to 0 if left blank. Has no upper bound. Required for queries against point and line data. 11 | # `Limit` refers to the number of features between 1 - 50 to return. Defaults to 5 if left blank. 12 | ``` 13 | -------------------------------------------------------------------------------- /lib/mapbox-sdk.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | -------------------------------------------------------------------------------- /lib/mapbox.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | require 'json' 3 | require 'mapbox/api_operations' 4 | require 'mapbox/authentication_error' 5 | 6 | module Mapbox 7 | @api_base = 'https://api.mapbox.com' 8 | @request_opts = {} 9 | 10 | LATITUDE_KEY = 'latitude'.freeze 11 | LONGITUDE_KEY = 'longitude'.freeze 12 | 13 | class << self 14 | attr_accessor :access_token, :api_base, :request_opts, :request_timeout, :request_open_timeout 15 | end 16 | 17 | def self.request(method, url, api_key, params={}, headers={}, api_base_url=nil) 18 | api_base_url = api_base_url || @api_base 19 | params = params || {} 20 | 21 | unless access_token ||= @access_token 22 | raise AuthenticationError.new('No API key provided. ' \ 23 | 'Set your API key using "Mapbox.access_token = ". ' \ 24 | 'You can generate API keys from the Mapbox web interface. ' \ 25 | 'See https://mapbox.com/developers for details, or email help@mapbox.com ' \ 26 | 'if you have any questions.') 27 | end 28 | 29 | url = api_base_url + url 30 | 31 | params['access_token'] = access_token 32 | 33 | case method.to_s.downcase.to_sym 34 | when :get, :head, :delete 35 | # Make params into GET parameters 36 | url += "#{URI.parse(url).query ? '&' : '?'}#{URI.encode_www_form(params)}" if params && params.any? 37 | payload = nil 38 | end 39 | 40 | @request_opts = {:verify_ssl => OpenSSL::SSL::VERIFY_PEER, 41 | :ssl_ca_file => @ssl_bundle_path} 42 | 43 | @request_opts.update( 44 | :method => method, 45 | :open_timeout => @request_open_timeout || 30, 46 | :payload => payload, 47 | :url => url, 48 | :timeout => @request_timeout || 80) 49 | 50 | begin 51 | response = execute_request(@request_opts) 52 | rescue SocketError => e 53 | handle_restclient_error(e, api_base_url) 54 | rescue NoMethodError => e 55 | # Work around RestClient bug 56 | if e.message =~ /\WRequestFailed\W/ 57 | e = StandardError.new('Unexpected HTTP response code') 58 | handle_restclient_error(e, api_base_url) 59 | else 60 | raise 61 | end 62 | rescue RestClient::ExceptionWithResponse => e 63 | if e.response 64 | handle_api_error(e, e.response) 65 | else 66 | handle_restclient_error(e, api_base_url) 67 | end 68 | rescue RestClient::Exception, Errno::ECONNREFUSED => e 69 | handle_restclient_error(e, api_base_url) 70 | end 71 | 72 | [parse(response), api_key] 73 | end 74 | 75 | def self.uri_encode(params) 76 | params. 77 | map { |k,v| "#{k}=#{url_encode(v)}" }.join('&') 78 | end 79 | 80 | def self.url_encode(key) 81 | URI.encode_www_form_component(key.to_s) 82 | end 83 | 84 | def self.execute_request(opts) 85 | RestClient::Request.execute(opts) 86 | end 87 | 88 | def self.parse(response) 89 | begin 90 | # Would use :symbolize_names => true, but apparently there is 91 | # some library out there that makes symbolize_names not work. 92 | response = JSON.parse(response.body) 93 | rescue JSON::ParserError 94 | raise general_api_error(response.code, response.body) 95 | end 96 | 97 | response 98 | end 99 | 100 | def self.general_api_error(rcode, rbody) 101 | StandardError.new("Invalid response object from API: #{rbody.inspect} " + 102 | "(HTTP response code was #{rcode})") 103 | end 104 | 105 | def self.handle_api_error(rcode, rbody) 106 | begin 107 | error_obj = JSON.parse(rbody) 108 | error = error_obj[:error] or raise StandardError.new # escape from parsing 109 | 110 | rescue JSON::ParserError, StandardError 111 | raise general_api_error(rcode, rbody) 112 | end 113 | 114 | case rcode 115 | when 400, 404 116 | raise invalid_request_error error, rcode, rbody, error_obj 117 | when 401 118 | raise authentication_error error, rcode, rbody, error_obj 119 | else 120 | raise api_error error, rcode, rbody, error_obj 121 | end 122 | 123 | end 124 | 125 | def self.invalid_request_error(error, rcode, rbody, error_obj) 126 | StandardError.new(error[:message], error[:param], rcode, 127 | rbody, error_obj) 128 | end 129 | 130 | def self.authentication_error(error, rcode, rbody, error_obj) 131 | AuthenticationError.new(error[:message], rcode, rbody, error_obj) 132 | end 133 | 134 | def self.api_error(error, rcode, rbody, error_obj) 135 | StandardError.new(error[:message], rcode, rbody, error_obj) 136 | end 137 | 138 | def self.handle_restclient_error(e, api_base_url=nil) 139 | api_base_url = @api_base unless api_base_url 140 | connection_message = "Please check your internet connection and try again. " \ 141 | "If this problem persists, you should check Mapbox's service status at " \ 142 | "https://status.mapbox.com/, or let us know at help@mapbox.com." 143 | 144 | case e 145 | when RestClient::RequestTimeout 146 | message = "Could not connect to Mapbox (#{api_base_url}). #{connection_message}" 147 | 148 | when RestClient::ServerBrokeConnection 149 | message = "The connection to the server (#{api_base_url}) broke before the " \ 150 | "request completed. #{connection_message}" 151 | 152 | when RestClient::SSLCertificateNotVerified 153 | message = "Could not verify Mapbox's SSL certificate. " \ 154 | "Please make sure that your network is not intercepting certificates. " \ 155 | "(Try going to https://api.mapbox.com/ in your browser.) " \ 156 | "If this problem persists, let us know at help@mapbox.com." 157 | 158 | when SocketError 159 | message = "Unexpected error communicating when trying to connect to Mapbox. " \ 160 | "You may be seeing this message because your DNS is not working. " \ 161 | "To check, try running 'host mapbox.com' from the command line." 162 | 163 | else 164 | message = "Unexpected error communicating with Mapbox. " \ 165 | "If this problem persists, let us know at help@mapbox.com." 166 | 167 | end 168 | 169 | raise StandardError.new(message + "\n\n(Network error: #{e.message})") 170 | end 171 | 172 | module HashUtils 173 | def xy_from_hash h = {} 174 | [ h.fetch(:longitude){ h[LONGITUDE_KEY] }, 175 | h.fetch(:latitude){ h[LATITUDE_KEY] } ] 176 | end 177 | end 178 | end 179 | 180 | # services 181 | require 'mapbox/geocoder' 182 | require 'mapbox/directions' 183 | require 'mapbox/tilequery' 184 | require 'mapbox/isochrone' 185 | require 'mapbox/matrix' 186 | require 'mapbox/map_matching' 187 | require 'mapbox/optimization' 188 | -------------------------------------------------------------------------------- /lib/mapbox/api_operations.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | module APIOperations 3 | module Request 4 | module ClassMethods 5 | OPTS_KEYS_TO_PERSIST = Set[:access_token, :api_base] 6 | 7 | def request(method, url, params={}, opts={}) 8 | headers = opts.clone 9 | access_token = headers.delete(:access_token) 10 | api_base = headers.delete(:api_base) 11 | # Assume all remaining opts must be headers 12 | 13 | response, opts[:api_key] = Mapbox.request(method, url, access_token, params, headers, api_base) 14 | 15 | # Hash#select returns an array before 1.9 16 | opts_to_persist = {} 17 | opts.each do |k, v| 18 | if OPTS_KEYS_TO_PERSIST.include?(k) 19 | opts_to_persist[k] = v 20 | end 21 | end 22 | 23 | [response, opts_to_persist] 24 | end 25 | end 26 | 27 | def self.included(base) 28 | base.extend(ClassMethods) 29 | end 30 | 31 | protected 32 | 33 | def request(method, url, params={}, opts={}) 34 | opts = @opts.merge(opts) 35 | self.class.request(method, url, params, opts) 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/mapbox/authentication_error.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class MapboxError < StandardError 3 | end 4 | 5 | class AuthenticationError < MapboxError 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/mapbox/directions.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class Directions 3 | include Mapbox::APIOperations::Request 4 | extend Mapbox::HashUtils 5 | 6 | def self.assemble_params(options={}) 7 | alternatives = options[:alternatives] 8 | annotations = options[:annotations] 9 | approaches = options[:approaches] 10 | banner_instructions = options[:banner_instructions] 11 | bearings = options[:bearings] 12 | continue_straight = options[:continue_straight] 13 | exclude = options[:exclude] 14 | geometries = options[:geometries] 15 | language = options[:language] 16 | overview = options[:overview] 17 | radiuses = options[:radiuses] 18 | roundabout_exits = options[:roundabout_exits] 19 | steps = options[:steps] 20 | voice_instructions = options[:voice_instructions] 21 | voice_units = options[:voice_units] 22 | waypoint_names = options[:waypoint_names] 23 | 24 | params = '' 25 | opts = options.select { |key, value| key != :approaches && key != :bearings && key != :radiuses && key != :waypoint_names } 26 | if opts.length > 0 27 | params += "#{params.length > 0 ? '&' : '?'}#{URI.encode_www_form(opts)}" 28 | end 29 | 30 | if approaches then 31 | params += "#{params.length > 0 ? '&' : '?'}approaches=#{approaches.join(';')}" 32 | end 33 | 34 | if bearings then 35 | params += "#{params.length > 0 ? '&' : '?'}bearings=#{bearings.map {|p| bearings.join ','}.join ';'}" 36 | end 37 | 38 | if radiuses then 39 | params += "#{params.length > 0 ? '&' : '?'}radiuses=#{radiuses.join ';'}" 40 | end 41 | 42 | if waypoint_names then 43 | params += "#{params.length > 0 ? '&' : '?'}waypoint_names=#{waypoint_names.join ';'}" 44 | end 45 | 46 | return params 47 | end 48 | 49 | def self.directions(waypoints, profile, options={}) 50 | formatted_waypoints = waypoints.map {|p| xy_from_hash(p).join ','}.join ';' 51 | params = self.assemble_params(options) 52 | 53 | return request( 54 | :get, 55 | "/directions/v5/mapbox/#{profile}/#{formatted_waypoints}.json#{params}", 56 | nil) 57 | end 58 | end 59 | end -------------------------------------------------------------------------------- /lib/mapbox/geocoder.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | require 'json' 3 | require 'uri' 4 | 5 | module Mapbox 6 | class Geocoder 7 | include Mapbox::APIOperations::Request 8 | extend Mapbox::HashUtils 9 | 10 | def self.assemble_params(options={}) 11 | proximity = options[:proximity] 12 | bbox = options[:bbox] 13 | types = options[:types] 14 | params = '' 15 | opts = options.select { |key, value| key != :proximity && key != :bbox && key != :types} 16 | if opts.length > 0 17 | params += "#{params.length > 0 ? '&' : '?'}#{URI.encode_www_form(opts)}" 18 | end 19 | 20 | if proximity then 21 | lon = proximity[:longitude].round(3) 22 | lat = proximity[:latitude].round(3) 23 | params += "#{params.length > 0 ? '&' : '?'}proximity=#{lon}%2C#{lat}" 24 | end 25 | 26 | if bbox then 27 | params += "#{params.length > 0 ? '&' : '?'}bbox=#{bbox.join('%2C')}" 28 | end 29 | 30 | if types then 31 | params += "#{params.length > 0 ? '&' : '?'}types=#{types.join('%2C')}" 32 | end 33 | 34 | return params 35 | end 36 | 37 | def self.geocode_forward(query, options={}, dataset='mapbox.places') 38 | params = self.assemble_params(options) 39 | 40 | return request( 41 | :get, 42 | "/geocoding/v5/#{dataset}/#{URI.encode_www_form_component(query)}.json#{params}", 43 | nil) 44 | end 45 | 46 | def self.geocode_reverse(location, options={}, dataset='mapbox.places') 47 | location[:longitude] = location[:longitude].round(5) 48 | location[:latitude] = location[:latitude].round(5) 49 | 50 | params = self.assemble_params(options) 51 | 52 | return request( 53 | :get, 54 | "/geocoding/v5/#{dataset}/#{xy_from_hash(location).join(',')}.json#{params}", 55 | nil) 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/mapbox/isochrone.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class Isochrone 3 | include Mapbox::APIOperations::Request 4 | 5 | def self.assemble_params(options={}) 6 | contours_minutes = options[:contours_minutes] 7 | contours_colors = options[:contours_colors] 8 | 9 | params = '' 10 | opts = options.select { |key, value| key != :contours_minutes && key != :contours_colors } 11 | if opts.length > 0 12 | params += "#{params.length > 0 ? '&' : '?'}#{URI.encode_www_form(opts)}" 13 | end 14 | 15 | if contours_minutes then 16 | params += "#{params.length > 0 ? '&' : '?'}contours_minutes=#{contours_minutes.join(',')}" 17 | end 18 | 19 | if contours_colors then 20 | params += "#{params.length > 0 ? '&' : '?'}contours_colors=#{contours_colors.join(',')}" 21 | end 22 | 23 | return params 24 | end 25 | 26 | def self.isochrone(profile, coordinates, options={}) 27 | params = self.assemble_params(options) 28 | 29 | return request( 30 | :get, 31 | "/isochrone/v1/mapbox/#{profile}/#{coordinates}#{params}", 32 | nil) 33 | end 34 | end 35 | end -------------------------------------------------------------------------------- /lib/mapbox/map_matching.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class MapMatching 3 | include Mapbox::APIOperations::Request 4 | extend Mapbox::HashUtils 5 | 6 | def self.assemble_params(options={}) 7 | annotations = options[:annotations] 8 | approaches = options[:approaches] 9 | radiuses = options[:radiuses] 10 | timestamps = options[:timestamps] 11 | waypoint_names = options[:waypoint_names] 12 | waypoints = options[:waypoints] 13 | 14 | params = '' 15 | opts = options.select { |key, value| key != :annotations && key != :approaches && key != :radiuses && key != :timestamps && key != :waypoint_names && key != :waypoints } 16 | if opts.length > 0 17 | params += "#{params.length > 0 ? '&' : '?'}#{URI.encode_www_form(opts)}" 18 | end 19 | 20 | if annotations then 21 | params += "#{params.length > 0 ? '&' : '?'}annotations=#{annotations.join(',')}" 22 | end 23 | 24 | if approaches then 25 | params += "#{params.length > 0 ? '&' : '?'}approaches=#{approaches.join(';')}" 26 | end 27 | 28 | if radiuses then 29 | params += "#{params.length > 0 ? '&' : '?'}radiuses=#{radiuses.join ';'}" 30 | end 31 | 32 | if timestamps then 33 | params += "#{params.length > 0 ? '&' : '?'}timestamps=#{timestamps.join ';'}" 34 | end 35 | 36 | if waypoint_names then 37 | params += "#{params.length > 0 ? '&' : '?'}waypoint_names=#{waypoint_names.join ';'}" 38 | end 39 | 40 | if waypoints then 41 | params += "#{params.length > 0 ? '&' : '?'}waypoints=#{waypoints.join ';'}" 42 | end 43 | 44 | return params 45 | end 46 | 47 | def self.map_matching(waypoints, profile, options={}) 48 | formatted_waypoints = waypoints.map {|p| xy_from_hash(p).join ','}.join ';' 49 | params = self.assemble_params(options) 50 | 51 | return request( 52 | :get, 53 | "/matching/v5/mapbox/#{profile}/#{formatted_waypoints}.json#{params}", 54 | nil) 55 | end 56 | end 57 | end -------------------------------------------------------------------------------- /lib/mapbox/matrix.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class Matrix 3 | include Mapbox::APIOperations::Request 4 | extend Mapbox::HashUtils 5 | 6 | def self.assemble_params(options={}) 7 | opts = options.dup 8 | 9 | self.joinArrayParam(opts, :destinations) 10 | self.joinArrayParam(opts, :annotations, ',') 11 | self.joinArrayParam(opts, :approaches) 12 | self.joinArrayParam(opts, :sources) 13 | 14 | return "?#{URI.encode_www_form(opts)}" 15 | end 16 | 17 | def self.joinArrayParam(opts, name, joinSymbol = ';') 18 | if opts[name].kind_of?(Array) 19 | opts[name] = opts[name].join(joinSymbol) 20 | end 21 | end 22 | 23 | def self.matrix(waypoints, profile, options={}) 24 | formatted_waypoints = waypoints.map {|p| xy_from_hash(p).join ','}.join ';' 25 | params = self.assemble_params(options) 26 | return request( 27 | :get, 28 | "/directions-matrix/v1/mapbox/#{profile}/#{formatted_waypoints}.json#{params}", 29 | nil) 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /lib/mapbox/optimization.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class Optimization 3 | include Mapbox::APIOperations::Request 4 | extend Mapbox::HashUtils 5 | 6 | def self.assemble_params(options={}) 7 | annotations = options[:annotations] 8 | approaches = options[:approaches] 9 | distributions = options[:distributions] 10 | radiuses = options[:radiuses] 11 | 12 | params = '' 13 | opts = options.select { |key, value| key != :annotations && key != :approaches && key != :distributions && key != :radiuses } 14 | if opts.length > 0 15 | params += "#{params.length > 0 ? '&' : '?'}#{URI.encode_www_form(opts)}" 16 | end 17 | 18 | if annotations then 19 | params += "#{params.length > 0 ? '&' : '?'}annotations=#{annotations.join(',')}" 20 | end 21 | 22 | if approaches then 23 | params += "#{params.length > 0 ? '&' : '?'}approaches=#{approaches.join(';')}" 24 | end 25 | 26 | if distributions then 27 | params += "#{params.length > 0 ? '&' : '?'}distributions=#{distributions.join(';')}" 28 | end 29 | 30 | if radiuses then 31 | params += "#{params.length > 0 ? '&' : '?'}radiuses=#{radiuses.join(';')}" 32 | end 33 | 34 | return params 35 | end 36 | 37 | def self.optimization(waypoints, profile, options={}) 38 | formatted_waypoints = waypoints.map {|p| xy_from_hash(p).join ','}.join ';' 39 | params = self.assemble_params(options) 40 | 41 | return request( 42 | :get, 43 | "/optimized-trips/v1/mapbox/#{profile}/#{formatted_waypoints}.json#{params}", 44 | nil) 45 | end 46 | end 47 | end -------------------------------------------------------------------------------- /lib/mapbox/tilequery.rb: -------------------------------------------------------------------------------- 1 | module Mapbox 2 | class Tilequery 3 | include Mapbox::APIOperations::Request 4 | extend Mapbox::HashUtils 5 | 6 | def self.tilequery(mapid, location, radius, limit) 7 | lon = location['longitude'].round(5) 8 | lat = location['latitude'].round(5) 9 | return request( 10 | :get, 11 | "/v4/#{mapid}/tilequery/#{lon},#{lat}.json?radius=#{radius}&limit=#{limit}", 12 | nil) 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /mapbox-sdk.gemspec: -------------------------------------------------------------------------------- 1 | $:.unshift(File.join(File.dirname(__FILE__), 'lib')) 2 | 3 | spec = Gem::Specification.new do |s| 4 | s.name = 'mapbox-sdk' 5 | s.version = '2.3.3' 6 | s.summary = 'Ruby bindings for the Mapbox API' 7 | s.description = '' 8 | s.authors = ['Tom MacWright'] 9 | s.email = ['tom@mapbox.org'] 10 | s.homepage = 'https://mapbox.com/developers' 11 | s.license = 'MIT' 12 | 13 | s.add_dependency('rest-client', '~> 2.1.0') 14 | 15 | s.add_development_dependency('mocha', '~> 0.13.2') 16 | s.add_development_dependency('shoulda', '~> 3.4.0') 17 | s.add_development_dependency('test-unit') 18 | s.add_development_dependency('rake') 19 | 20 | s.files = `git ls-files`.split("\n") 21 | s.test_files = `git ls-files -- test/*`.split("\n") 22 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 23 | s.require_paths = ['lib'] 24 | end 25 | -------------------------------------------------------------------------------- /test/all_tests.rb: -------------------------------------------------------------------------------- 1 | require 'coveralls' 2 | Coveralls.wear! 3 | 4 | Dir[File.dirname(File.absolute_path(__FILE__)) + '/**/*_test.rb'].each {|file| require file } -------------------------------------------------------------------------------- /test/directions_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class DirectionsTest < Test::Unit::TestCase 8 | should "#directions" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::Directions.directions([ 11 | { 12 | :longitude => -100, 13 | :latitude => 38 14 | }, 15 | { 16 | :longitude => -90, 17 | :latitude => 38 18 | } 19 | ], "cycling", { 20 | geometries: "geojson" 21 | }) 22 | assert result 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/geocoding_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class GeocodingTest < Test::Unit::TestCase 8 | 9 | def setup 10 | Mapbox.access_token = ENV["MapboxAccessToken"] 11 | end 12 | 13 | def teardown 14 | Mapbox.request_open_timeout = nil 15 | Mapbox.request_timeout = nil 16 | end 17 | 18 | should "#geocode_forward" do 19 | result = Mapbox::Geocoder.geocode_forward("Chester, NJ") 20 | assert result 21 | end 22 | 23 | should "set_default_timeouts" do 24 | result = Mapbox::Geocoder.geocode_forward("Chester, NJ") 25 | assert Mapbox.request_opts[:timeout] = 80 26 | assert Mapbox.request_opts[:open_timeout] = 30 27 | end 28 | 29 | should "#geocode_forward (rounded proximity to 3 decimal places)" do 30 | result = Mapbox::Geocoder.geocode_forward("Chester, NJ", {:proximity => {:longitude => 0.1234567, :latitude => -10.987654}}) 31 | assert result 32 | assert Mapbox.request_opts[:url].include? '?proximity=0.123%2C-10.988&' 33 | end 34 | 35 | should "#geocode_forward (include bbox param)" do 36 | result = Mapbox::Geocoder.geocode_forward("Washington", {:bbox => [-78.3284,38.6039,-78.0428,38.7841]}) 37 | assert result 38 | assert Mapbox.request_opts[:url].include? '?bbox=-78.3284%2C38.6039%2C-78.0428%2C38.7841'; 39 | end 40 | 41 | should "#geocode_forward (include extra param)" do 42 | result = Mapbox::Geocoder.geocode_forward("Washington", {:bbox => [-78.3284,38.6039,-78.0428,38.7841], :foo_key => "foo_val", :bar_key => "bar_val"}) 43 | assert result 44 | assert Mapbox.request_opts[:url].include? '?foo_key=foo_val&bar_key=bar_val'; 45 | end 46 | 47 | should "#geocode_forward (include country param)" do 48 | result = Mapbox::Geocoder.geocode_forward("Washington", {:country => "ca"}) 49 | assert result 50 | assert Mapbox.request_opts[:url].include? '?country=ca'; 51 | end 52 | 53 | should "#geocode_forward (include types param)" do 54 | result = Mapbox::Geocoder.geocode_forward("Washington", {:types => ['poi.landmark', 'address'], :foo_key => "foo_val", :bar_key => "bar_val"}) 55 | assert result 56 | assert Mapbox.request_opts[:url].include? '?foo_key=foo_val&bar_key=bar_val&types=poi.landmark%2Caddress'; 57 | end 58 | 59 | should "#geocode_reverse" do 60 | result = Mapbox::Geocoder.geocode_reverse({ 61 | :latitude => 38, 62 | :longitude => -100 63 | }) 64 | assert result 65 | end 66 | 67 | should "#geocode_reverse (rounded coordinates to 5 decimal places)" do 68 | result = Mapbox::Geocoder.geocode_reverse({ 69 | :latitude => 1.23456789, 70 | :longitude => -99.8765432 71 | }) 72 | for coord in result.first['query'] do 73 | assert coord.to_s.split('.')[-1].length <= 5 74 | end 75 | end 76 | 77 | should "set_custom_timeouts" do 78 | Mapbox.request_timeout = 10 79 | Mapbox.request_open_timeout = 5 80 | result = Mapbox::Geocoder.geocode_forward("Chester, NJ", {:proximity => {:longitude => 0.1234567, :latitude => -10.987654}}) 81 | assert Mapbox.request_opts[:timeout] == 10 82 | assert Mapbox.request_opts[:open_timeout] == 5 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /test/isochrone_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class IsochroneTest < Test::Unit::TestCase 8 | should "#isochrone" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::Isochrone.isochrone( 11 | "walking", "-118.22258,33.99038", {contours_minutes: [5,10,15]}) 12 | assert result 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/map_matching_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class MapMatchingTest < Test::Unit::TestCase 8 | should "#map match with just coordinates and profile" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::MapMatching.map_matching([{ 11 | "longitude" => -117.17282, 12 | "latitude" => 32.71204 13 | }, { 14 | "longitude" => -117.17288, 15 | "latitude" => 32.71225 16 | }, { 17 | "longitude" => -117.17293, 18 | "latitude" => 32.71244 19 | },{ 20 | "longitude" => -117.17292, 21 | "latitude" => 32.71256 22 | }], "driving") 23 | assert result 24 | end 25 | should "#map match with optional params" do 26 | Mapbox.access_token = ENV["MapboxAccessToken"] 27 | result = Mapbox::MapMatching.map_matching([{ 28 | "longitude" => -117.17282, 29 | "latitude" => 32.71204 30 | }, { 31 | "longitude" => -117.17288, 32 | "latitude" => 32.71225 33 | }, { 34 | "longitude" => -117.17293, 35 | "latitude" => 32.71244 36 | }, { 37 | "longitude" => -117.17292, 38 | "latitude" => 32.71256 39 | }], "driving", { 40 | annotations: ["duration", "distance", "speed"], 41 | approaches: ["curb","curb","curb","curb"] 42 | }) 43 | assert result 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /test/mapbox_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class ModuleTest < Test::Unit::TestCase 8 | should "throw if access_token is not defined" do 9 | assert_raise { 10 | Mapbox.request() 11 | } 12 | end 13 | 14 | should "allow access token to be set" do 15 | Mapbox.access_token = "foo" 16 | end 17 | 18 | should "allow request_timeout to be set" do 19 | Mapbox.request_timeout = 5 20 | end 21 | 22 | should "allow request_open_timeout to be set" do 23 | Mapbox.request_open_timeout = 5 24 | end 25 | end 26 | 27 | class HashUtilTest < Test::Unit::TestCase 28 | include Mapbox::HashUtils 29 | 30 | should "return array of long,lat from hash with string keys" do 31 | assert_equal xy_from_hash({'longitude' => -122, 'latitude' => 45}), 32 | [-122, 45] 33 | end 34 | 35 | should "return array of long,lat from hash with symbol keys" do 36 | assert_equal xy_from_hash({:longitude => -122, :latitude => 45}), 37 | [-122, 45] 38 | end 39 | 40 | should "return array of long,lat from hash with mixed keys" do 41 | assert_equal xy_from_hash({:longitude => -122, 'latitude' => 45}), 42 | [-122, 45] 43 | end 44 | 45 | should "raise arguemnt error if not given a hash" do 46 | assert_raise { xy_from_hash(Object.new) } 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/matrix_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class MatrixTest < Test::Unit::TestCase 8 | should "#matrix with just coordinates and profile" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::Matrix.matrix([{ 11 | "longitude" => -122.42, 12 | "latitude" => 37.78 13 | }, { 14 | "longitude" => -122.45, 15 | "latitude" => 37.91 16 | }, { 17 | "longitude" => -122.48, 18 | "latitude" => 37.73 19 | }], "driving") 20 | assert result 21 | end 22 | should "#matrix with optional params" do 23 | Mapbox.access_token = ENV["MapboxAccessToken"] 24 | result = Mapbox::Matrix.matrix([{ 25 | "longitude" => -122.42, 26 | "latitude" => 37.78 27 | }, { 28 | "longitude" => -122.45, 29 | "latitude" => 37.91 30 | }, { 31 | "longitude" => -122.48, 32 | "latitude" => 37.73 33 | }], "cycling", { 34 | annotations: ["duration", "distance"], 35 | approaches: ["curb","curb","curb"] 36 | }) 37 | assert result 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /test/optimization_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class MatrixTest < Test::Unit::TestCase 8 | should "#optimization with just coordinates and profile" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::Optimization.optimization([{ 11 | "longitude" => -122.42, 12 | "latitude" => 37.78 13 | }, { 14 | "longitude" => -122.45, 15 | "latitude" => 37.91 16 | }, { 17 | "longitude" => -122.48, 18 | "latitude" => 37.73 19 | }], "walking") 20 | assert result 21 | end 22 | should "#optimization with optional params" do 23 | Mapbox.access_token = ENV["MapboxAccessToken"] 24 | result = Mapbox::Optimization.optimization([{ 25 | "longitude" => -122.42, 26 | "latitude" => 37.78 27 | }, { 28 | "longitude" => -122.45, 29 | "latitude" => 37.91 30 | }, { 31 | "longitude" => -122.48, 32 | "latitude" => 37.73 33 | }], "cycling", { 34 | annotations: ["duration", "distance"], 35 | approaches: ["curb","curb","curb"] 36 | }) 37 | assert result 38 | end 39 | should "#optimization with an empty bearing" do 40 | Mapbox.access_token = ENV["MapboxAccessToken"] 41 | result = Mapbox::Optimization.optimization([{ 42 | "longitude" => -122.42, 43 | "latitude" => 37.78 44 | }, { 45 | "longitude" => -122.45, 46 | "latitude" => 37.91 47 | }, { 48 | "longitude" => -122.48, 49 | "latitude" => 37.73 50 | }], "driving", { 51 | bearings: "45,90;;90,1" 52 | }) 53 | assert result 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /test/tilequery_test.rb: -------------------------------------------------------------------------------- 1 | require 'mapbox' 2 | require 'test/unit' 3 | require 'mocha/setup' 4 | require 'shoulda' 5 | 6 | module Mapbox 7 | class TilequeryTest < Test::Unit::TestCase 8 | should "#tilequery" do 9 | Mapbox.access_token = ENV["MapboxAccessToken"] 10 | result = Mapbox::Tilequery.tilequery( 11 | "mapbox.mapbox-streets-v7", {"longitude" => -122.42901, "latitude" => 37.80633}, 5, 10) 12 | assert result 13 | end 14 | end 15 | end --------------------------------------------------------------------------------