|
1 | 1 | # Introduction |
2 | 2 |
|
3 | 3 | Easy to use Google Maps in your Flask application |
| 4 | + |
| 5 | +## requires |
| 6 | + |
| 7 | +- Python 3.6+ |
| 8 | +- Jinja |
| 9 | +- Flask |
| 10 | +- A google api key [get here](https://developers.google.com/maps/documentation/javascript/get-api-key) |
| 11 | + |
| 12 | +## Contribute |
| 13 | + |
| 14 | +To contribute with the project, clone it, create a virtualenv and install all of you need to dev, see below: |
| 15 | + |
| 16 | +```bash |
| 17 | +git clone https://github.com/flask-extensions/Flask-GoogleMaps.git |
| 18 | +cd Flask-GoogleMaps |
| 19 | +poetry use env 3.8 # just to create virtualenv at the first time |
| 20 | +poetry shell # activate virtualenv |
| 21 | +poetry install # to install all for dev |
| 22 | +``` |
| 23 | + |
| 24 | +## Installation |
| 25 | + |
| 26 | +To use in your project just use your dependency manager to install it, with pip is like this: |
| 27 | + |
| 28 | +```bash |
| 29 | +pip install flask-googlemaps |
| 30 | +``` |
| 31 | + |
| 32 | +## How it works |
| 33 | + |
| 34 | +Flask-GoogleMaps includes some global functions and template filters in your Jinja environment, also it allows you to use the Map in views if needed. |
| 35 | + |
| 36 | +### registering |
| 37 | + |
| 38 | +in your app |
| 39 | + |
| 40 | +```python |
| 41 | + |
| 42 | +from flask import Flask |
| 43 | +from flask_googlemaps import GoogleMaps |
| 44 | + |
| 45 | +app = Flask(__name__) |
| 46 | + |
| 47 | +# you can set key as config |
| 48 | +app.config['GOOGLEMAPS_KEY'] = "8JZ7i18MjFuM35dJHq70n3Hx4" |
| 49 | + |
| 50 | +# Initialize the extension |
| 51 | +GoogleMaps(app) |
| 52 | + |
| 53 | +# you can also pass the key here if you prefer |
| 54 | +GoogleMaps(app, key="8JZ7i18MjFuM35dJHq70n3Hx4") |
| 55 | + |
| 56 | +``` |
| 57 | + |
| 58 | +In template |
| 59 | + |
| 60 | +```html |
| 61 | +{{googlemap("my_awesome_map", lat=0.23234234, lng=-0.234234234, markers=[(0.12, |
| 62 | +-0.45345), ...])}} |
| 63 | +``` |
| 64 | + |
| 65 | +That's it! now you have some template filters and functions to use, more details in examples and screenshot below. |
| 66 | + |
| 67 | +### Usage |
| 68 | + |
| 69 | +- You can create the map in the view and then send to the template context |
| 70 | +- you can use the template functions and filters directly |
| 71 | + |
| 72 | +#### 1. View |
| 73 | + |
| 74 | +```python |
| 75 | + |
| 76 | +from flask import Flask, render_template |
| 77 | +from flask_googlemaps import GoogleMaps |
| 78 | +from flask_googlemaps import Map |
| 79 | + |
| 80 | +app = Flask(__name__, template_folder=".") |
| 81 | +GoogleMaps(app) |
| 82 | + |
| 83 | +@app.route("/") |
| 84 | +def mapview(): |
| 85 | + # creating a map in the view |
| 86 | + mymap = Map( |
| 87 | + identifier="view-side", |
| 88 | + lat=37.4419, |
| 89 | + lng=-122.1419, |
| 90 | + markers=[(37.4419, -122.1419)] |
| 91 | + ) |
| 92 | + sndmap = Map( |
| 93 | + identifier="sndmap", |
| 94 | + lat=37.4419, |
| 95 | + lng=-122.1419, |
| 96 | + markers=[ |
| 97 | + { |
| 98 | + 'icon': 'http://maps.google.com/mapfiles/ms/icons/green-dot.png', |
| 99 | + 'lat': 37.4419, |
| 100 | + 'lng': -122.1419, |
| 101 | + 'infobox': "<b>Hello World</b>" |
| 102 | + }, |
| 103 | + { |
| 104 | + 'icon': 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png', |
| 105 | + 'lat': 37.4300, |
| 106 | + 'lng': -122.1400, |
| 107 | + 'infobox': "<b>Hello World from other place</b>" |
| 108 | + } |
| 109 | + ] |
| 110 | + ) |
| 111 | + return render_template('example.html', mymap=mymap, sndmap=sndmap) |
| 112 | + |
| 113 | +if __name__ == "__main__": |
| 114 | + app.run(debug=True) |
| 115 | + |
| 116 | +``` |
| 117 | + |
| 118 | +##### `Map()` Parameters |
| 119 | + |
| 120 | +- **lat**: The latitude coordinate for centering the map. |
| 121 | +- **lng**: The longitutde coordinate for centering the map. |
| 122 | +- **zoom**: The zoom level. Defaults to `13`. |
| 123 | +- **maptype**: The map type - `ROADMAP`, `SATELLITE`, `HYBRID`, `TERRAIN`. Defaults to `ROADMAP`. |
| 124 | +- **markers**: Markers array of tuples having (**lat**, **lng**, infobox, icon). Defaults to `None`. |
| 125 | +- or **markers**: a list of dicts containing **icon, lat, lng, infobox**. |
| 126 | +- or **markers**: Markers dictionary with icon urls as keys and markers array as values. |
| 127 | +- **varname**: The instance variable name. |
| 128 | +- **style**: A string containing CSS styles. Defaults to `"height:300px;width:300px;margin:0;"`. |
| 129 | +- **identifier**: The CSS ID selector name. |
| 130 | +- **cls**: The CSS Class selector name. Defaults to `"map"`. |
| 131 | +- **language**: The map language. Defaults to `"en"`. |
| 132 | +- **region**: The map region. Defaults to `"US"`. |
| 133 | + |
| 134 | +Also controls True or False: |
| 135 | + |
| 136 | +- zoom_control |
| 137 | +- maptype_control |
| 138 | +- scale_control |
| 139 | +- scale_control |
| 140 | +- streetview_control |
| 141 | +- rotate_control |
| 142 | +- fullscreen_control |
| 143 | +- scroll_wheel |
| 144 | +- collapsible (map collapses by click on **varname**\_collapse button) |
| 145 | +- center_on_user_location (using HTML5 Geolocation) |
| 146 | + |
| 147 | +#### 2. Template |
| 148 | + |
| 149 | +```html |
| 150 | +<!DOCTYPE html> |
| 151 | +<html> |
| 152 | + <head> |
| 153 | + {{"decoupled-map"|googlemap_js(37.4419, -122.1419, markers=[(37.4419, |
| 154 | + -122.1419)])}} {{mymap.js}} {{sndmap.js}} |
| 155 | + </head> |
| 156 | + <body> |
| 157 | + <h1>Flask Google Maps Example</h1> |
| 158 | + |
| 159 | + <h2>Template function centered, no marker</h2> |
| 160 | + {{googlemap("simple-map", 37.4419, -122.1419)}} |
| 161 | + |
| 162 | + <h2>Template filter decoupled with single marker</h2> |
| 163 | + {{"decoupled-map"|googlemap_html(37.4419, -122.1419)}} |
| 164 | + |
| 165 | + <h2>Template function with multiple markers</h2> |
| 166 | + {% with map=googlemap_obj("another-map", 37.4419, -122.1419, |
| 167 | + markers=[(37.4419, -122.1419), (37.4300, -122.1400)]) %} {{map.html}} |
| 168 | + {{map.js}} {% endwith %} |
| 169 | + |
| 170 | + <h2>First map generated in view</h2> |
| 171 | + {{mymap.html}} |
| 172 | + |
| 173 | + <h2>Second map generated in view</h2> |
| 174 | + <h3>Example for different icons in multiple markers with infoboxes</h3> |
| 175 | + {{sndmap.html}} |
| 176 | + </body> |
| 177 | +</html> |
| 178 | +``` |
| 179 | + |
| 180 | +### Infobox |
| 181 | + |
| 182 | +Here's an example snippet of code: |
| 183 | + |
| 184 | +```python |
| 185 | + |
| 186 | + Map( |
| 187 | + identifier="catsmap", |
| 188 | + lat=37.4419, |
| 189 | + lng=-122.1419, |
| 190 | + markers=[ |
| 191 | + { |
| 192 | + 'icon': 'http://maps.google.com/mapfiles/ms/icons/green-dot.png', |
| 193 | + 'lat': 37.4419, |
| 194 | + 'lng': -122.1419, |
| 195 | + 'infobox': "<img src='cat1.jpg' />" |
| 196 | + }, |
| 197 | + { |
| 198 | + 'icon': 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png', |
| 199 | + 'lat': 37.4300, |
| 200 | + 'lng': -122.1400, |
| 201 | + 'infobox': "<img src='cat2.jpg' />" |
| 202 | + }, |
| 203 | + { |
| 204 | + 'icon': 'http://maps.google.com/mapfiles/ms/icons/yellow-dot.png', |
| 205 | + 'lat': 37.4500, |
| 206 | + 'lng': -122.1350, |
| 207 | + 'infobox': "<img src='cat3.jpg' />" |
| 208 | + } |
| 209 | + ] |
| 210 | + ) |
| 211 | + |
| 212 | +``` |
| 213 | + |
| 214 | +Which results in something like the following map: |
| 215 | +<img width="1439" alt="screen shot 2015-07-29 at 2 41 52 pm" src="https://cloud.githubusercontent.com/assets/8108300/8969650/13b0de7a-3602-11e5-9ed0-9f328ac9253f.png"> |
| 216 | + |
| 217 | +### Fit all markers within bounds |
| 218 | + |
| 219 | +Allow users to easily fit all markers within view on page load |
| 220 | + |
| 221 | +#### Without bounds |
| 222 | + |
| 223 | +```python |
| 224 | + |
| 225 | +@app.route('/map-unbounded/') |
| 226 | +def map_unbounded(): |
| 227 | +"""Create map with markers out of bounds.""" |
| 228 | + locations = [] # long list of coordinates |
| 229 | + map = Map( |
| 230 | + lat=locations[0].latitude, |
| 231 | + lng=locations[0].longitude, |
| 232 | + markers=[(loc.latitude, loc.longitude) for loc in locations] |
| 233 | + ) |
| 234 | + return render_template('map.html', map=map) |
| 235 | + |
| 236 | +``` |
| 237 | + |
| 238 | + |
| 239 | + |
| 240 | +#### With bounds |
| 241 | + |
| 242 | +```python |
| 243 | + |
| 244 | +@app.route('/map-bounded/') |
| 245 | +def map_bounded(): |
| 246 | +"""Create map with all markers within bounds.""" |
| 247 | + locations = [] # long list of coordinates |
| 248 | + map = Map( |
| 249 | + lat=locations[0].latitude, |
| 250 | + lng=locations[0].longitude, |
| 251 | + markers=[(loc.latitude, loc.longitude) for loc in locations], |
| 252 | + fit_markers_to_bounds = True |
| 253 | + ) |
| 254 | + return render_template('map.html', map=map) |
| 255 | + |
| 256 | +``` |
| 257 | + |
| 258 | + |
| 259 | + |
| 260 | +### Geocoding and Reverse Geocoding |
| 261 | + |
| 262 | +```python |
| 263 | +from flask_googlemaps import get_address, get_coordinates |
| 264 | +API_KEY = 'YOUR API KEY' |
| 265 | + |
| 266 | +#Reverse Geocoding: getting detailed address from coordinates of a location |
| 267 | +print(get_address(API_KEY,22.4761596,88.4149326)) |
| 268 | +#output: {'zip': '700150', 'country': 'India', 'state': 'West Bengal', 'city': 'Kolkata', 'locality': 'Kolkata', 'road': 'Techno City', 'formatted_address': 'Sirin Rd, Mauza Ranabhutia, Techno City, Kolkata, West Bengal 700150, India'} |
| 269 | + |
| 270 | + |
| 271 | +#Geocoding: getting coordinates from address text |
| 272 | +print(get_coordinates(API_KEY,'Netaji Subhash Engineering College Kolkata')) |
| 273 | +#output: {'lat': 22.4761596, 'lng': 88.4149326} |
| 274 | +``` |
| 275 | + |
| 276 | +### Run the example app |
| 277 | + |
| 278 | +```bash |
| 279 | +$ git clone https://github.com/flask-extensions/Flask-GoogleMaps |
| 280 | +$ cd Flask-GoogleMaps/ |
| 281 | +``` |
| 282 | + |
| 283 | +If you have Poetry |
| 284 | + |
| 285 | +```bash |
| 286 | +$ poetry install |
| 287 | +``` |
| 288 | + |
| 289 | +without poetry |
| 290 | + |
| 291 | +```bash |
| 292 | +$ pip install --upgrade pip |
| 293 | +$ pip install -e . |
| 294 | +$ pip install -r requirements.txt |
| 295 | +``` |
| 296 | + |
| 297 | +Run it. |
| 298 | + |
| 299 | +```bash |
| 300 | +$ FLASK_GOOGLEMAPS_KEY="YourKeyHERE" FLASK_APP=examples/example.py flask run |
| 301 | +running on localhost:5000 ..... |
| 302 | +``` |
| 303 | + |
| 304 | +Access: http://localhost:5000/ and http://localhost:5000/fullmap |
| 305 | + |
| 306 | +## Contribute with the Google Maps API |
| 307 | + |
| 308 | +Please see this page [developers.google.com/maps/documentation/javascript/tutorial](https://developers.google.com/maps/documentation/javascript/tutorial) and contribute! |
0 commit comments