📜 ⬆️ ⬇️

Google Maps API


Map service - why? Well, for example, I lived in our small province for 10 years, and then I took it and came to Moscow, and everything is so new for me. And where are the shops, bowling, cafes, leisure parks - you need to know where to spend the Moscow salary. But the trouble is how to find out? There used to be the Yellow Pages directory and there was a map and all of them by addresses. To find something took a lot of time. Now everything has become much easier. Here is a great example: http://www.pushkino.org/ . But that's not all.
I can track the weather, fires, traffic jams (by the way!) In real time.
My customer may not enter his address, but simply mark it on the map and I will know where to deliver the goods to him - what a cool solution, do not need all of this - "Marshal Blucher Avenue, 43, St. Petersburg, Russia."



Task for example


It’s better to learn practically, so let's do an example task in order to gain skills. Here is a rough work plan:
  1. Display the card (wow!)
  2. Set city
  3. Move the map to the city
  4. Marker to specify the address
  5. Add information
  6. Display the card (wow!)
  7. Save a marker with information (when clicked on it, bring it out)
  8. Avoid cluttering up (i.e., clustering) markers.

')

How to do?



API key

The API key is needed to use the map, i.e. when requesting all of their scripts and services, you need to add & key = [here is our key] in the parameters. But for http: // localhost it is not needed. Get it here: http://code.google.com/apis/maps/signup.html . By the way, it works without it on the site, but it may be temporary.
For v.3 not needed

Map \ Marker \ InfoWindow



For work we need 3 main objects. The first is the map.
The map is created very simply. We have some specific container:

<div id="map_canvas"></div> 


Connect the script:
 <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 


Initialize the map:

 function initialize() { var myLatlng = new google.maps.LatLng(-34.397, 150.644); var myOptions = { zoom: 8, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); } 


center: myLatlng is the coordinates of the center of the map
zoom is an increase during initialization
mapTypeId - type (political, physical, hybrid)
The map is ready!

The second is tags :

 var marker = new google.maps.Marker({ position: myLatlng, map: map, title:"Hello World!" }); 


position - the actual coordinates of the label
map - on which map label to place
title - when hovering the mouse, it will write “Hello World!”.

InfoWindow

 var contentString = '<div id="content">       </div>'; var infowindow = new google.maps.InfoWindow({ content: contentString }); var marker = new google.maps.Marker({ position: myLatlng, map: map, title: 'Uluru (Ayers Rock)' }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); 

content - content in the label

 google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); 
- when clicking on a label, show a window with information on a map with reference to a marker.

Geocoding

Geocoding is just a great library that allows you to do only 2 things:


The request looks like this. For example, we want to know where is Ivanovo. We write request:
http://maps.googleapis.com/maps/api/geocode/json?address=Ivanovo&sensor=false&language=en

And in the answer comes:
 { "status": "OK", "results": [ { "types": [ "locality", "political" ], "formatted_address": " ,  , ", -   "address_components": [ { -   "long_name": " ", "short_name": " ", "types": [ "locality", "political" ] }, { "long_name": " ", "short_name": " ", "types": [ "administrative_area_level_2", "political" ] }, { "long_name": " ", "short_name": " ", "types": [ "administrative_area_level_1", "political" ] }, { "long_name": "", "short_name": "RU", "types": [ "country", "political" ] } ], "geometry": { "location": { -  "lat": 56.9924086, "lng": 40.9677888 }, "location_type": "APPROXIMATE", "viewport": { -  "southwest": { "lat": 56.9699256, "lng": 40.9265167 }, "northeast": { "lat": 57.0148916, "lng": 41.0090609 } }, "bounds": { -  "southwest": { "lat": 56.9699256, "lng": 40.9265167 }, "northeast": { "lat": 57.0148916, "lng": 41.0090609 } } } } ] } 


The beauty is that it is possible to transmit the value in the address parameter in any language (Ivanovo, Ivanovo, <there was an Arabic script>), it is even better that St. Petersburg and St. Petersburg roll for St. Petersburg. True, there are shortcomings: my hometown Ivano-Frankivsk persistently calls Ivano-Frankivsk to, in the Ukrainian manner.
The second possibility is to find the address by coordinates:

http://maps.googleapis.com/maps/api/geocode/json?latlng=55.75320193022759,37.61922086773683&sensor=false&language=ru
we get:

 { "status": "OK", "results": [ { "types": [ "street_address" ], "formatted_address": " ., 3,  , , 109012", "address_components": [ { "long_name": "3", "short_name": "3", "types": [ "street_address" ] }, { "long_name": " .", "short_name": " .", "types": [ "route" ] }, { "long_name": "", "short_name": "", "types": [ "sublocality", "political" ] }, { "long_name": " ", "short_name": " ", "types": [ "locality", "political" ] }, { "long_name": " ", "short_name": " ", "types": [ "administrative_area_level_2", "political" ] }, { "long_name": "", "short_name": "", "types": [ "administrative_area_level_1", "political" ] }, { "long_name": "", "short_name": "RU", "types": [ "country", "political" ] }, { "long_name": "109012", "short_name": "109012", "types": [ "postal_code" ] } ], "geometry": { "location": { "lat": 55.7546971, "lng": 37.6215214 }, "location_type": "ROOFTOP", "viewport": { "southwest": { "lat": 55.7515495, "lng": 37.6183738 }, "northeast": { "lat": 55.7578447, "lng": 37.6246690 } } } }, { ... 


Super! In order to specify your address, you can simply click on your house, add an apartment - that's all. Sometimes it does not work, for example, if the houses are close to each other and read as 1 object, and not 2-3, they will have one address. It is especially bad when they are at the intersection of streets, and one house belongs to one street, and the second to perpendicular, but I think of necessity you can indicate the street, and you can drive the house and apartment. Very convenient solution for smartphones.
By the way, do not use jquery $ .getJSON to get data, use the Geocoder class ( http://code.google.com/apis/maps/documentation/javascript/reference.html#Geocoder ), it works better (i.e. means that getJSON does not work for me).

And now about not very good. Geocoder is a cool feature that you can use only 2500 requests per day. Google offers Google API Key Premier from $ 10,000 per year, and then the limit will be 100 thousand requests per day, and a bunch of cool add-ons, but I can't afford them.

Markercluster


When there are too many markers, it certainly looks awful. Therefore, it would be good to cluster all of these markers. Here on Habré I have already seen a discussion about this: http://habrahabr.ru/blogs/google/28621/
In general, there is a great tool (and here’s a whole set of http://code.google.com/apis/maps/articles/toomanymarkers.html ) that helps to make the crowds of markers not frighten us.
Before:

After:

This is exactly what we need.
This library can be downloaded here: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/
How to use.
Add a library

 <script type="text/javascript" src="/Media/script/map/markerclusterer_packed.js"></script> 


We make an array of markers without adding to the map:

 var markers = []; var marker = new google.maps.Marker({ position: latlng }); markers.push(marker); markerClusterer = new MarkerClusterer(_this.map, markers, { maxZoom: 13, gridSize: 50, styles: null }); 


maxZoom - the maximum zoom at which we still group the markers, then - no longer.
gridSize - the size of the grid cells, the smaller the value, the smaller the grouping grid
styles - additional styles

Code from the example


I will not write here what to collect, in fact, all the tools are ready, I will give links to the sources, and comment on some things.
The server code (asp.net mvc) is very small there, only 4 requests:

The main jquery code (here in full: cocosanka.ru/media/script/map/map.js ) There are comments, and all that.
Some features that require explanation:

Calculating the Zoom value across borders
(taken from here: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/43958790eafe037f/66e889029c555bee?fwc=2 )

 this.getZoom = function (bounds) { var width = $(".map").width(); var height = $(".map").height(); var dlat = Math.abs(bounds.getNorthEast().lat() - bounds.getSouthWest().lat()); var dlon = Math.abs(bounds.getNorthEast().lng() - bounds.getSouthWest().lng()); var max = 0; if (dlat > dlon) { max = dlat; } else { max = dlon; } var clat = Math.PI * Math.abs(bounds.getSouthWest().lat() + bounds.getNorthEast().lat()) / 360.; var C = 0.0000107288; var z0 = Math.ceil(Math.log(dlat / (C * height)) / Math.LN2); var z1 = Math.ceil(Math.log(dlon / (C * width * Math.cos(clat))) / Math.LN2); //18 –   zoom  google.maps return 18 - ((z1 > z0) ? z1 : z0); } 

Function for "jump" marker:

 this.toggleBounceMarker = function() { if (_this.setMarker.getAnimation() != null) { _this.setMarker.setAnimation(null); } else { _this.setMarker.setAnimation(google.maps.Animation.BOUNCE); } } 


Getting an address:
 this.SetAddresses = function (results) { $(".address_list").show(); $(".address_list").empty(); var addressText = _this.ComposeAddress(results[0]); ... } //      this.ComposeAddress = function (item) { retAddress = ""; $.each(item.address_components, function (i, address_item) { var isOk = false; $.each(address_item.types, function (j, typeName) { //        () -     administrative_level_2 if (typeName != "street_address" && typeName != "locality") { isOk = true; } }); if (isOk) { if (retAddress == "") { retAddress = address_item.long_name; } else { retAddress = retAddress + ", " + address_item.long_name; } } }); return retAddress; } 

Total



The Google Maps API is a very cool and handy thing that is easy to use and understand. The only thing that is bad is the weak coverage of the regions in Russia, so the services that are supposed to be used in the depths of google.maps are of little interest, but everything is great for large cities (especially Moscow and St. Petersburg), as well as for Ukraine.
Geocoding is a very useful thing and, if used properly, can cost the money that is asked for it (well, either Microsoft or Yandex will come up with an analog already . Although as far as I know, cartographic information is worth a lot of investment.)

Sample \ source


You can look at a living example here: http://cocosanka.ru/map (may stop working if the limit in Geocoding is reached). Enter the city, then drag the marker, then load the image and save. When you click on the markers are displayed images.

Sources: https://bitbucket.org/chernikov/citylocator

Source: https://habr.com/ru/post/110460/


All Articles