Skip to content

Instantly share code, notes, and snippets.

@unglud
Created January 21, 2016 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unglud/7faf295e0b5efc09488f to your computer and use it in GitHub Desktop.
Save unglud/7faf295e0b5efc09488f to your computer and use it in GitHub Desktop.
Google maps Module. Can add marker, directions and draw path by directions
var ProjectMap = (function () {
"use strict";
var _center = {lat: 50.159573, lng: 71.918242}, // map center on load
_points = [],
_map = null,
_useDirectios = false, // generate directions with google.maps.DirectionsService() or use simple google.maps.Polyline
_cache = [], // cache for google.maps.Geocoder()
_isDraggable = !('ontouchstart' in document.documentElement);
// constructor
var module = function (json, directions) {
if (directions != undefined) _useDirectios = directions;
addPoints(json);
renderMap();
};
var renderMap = function () {
var mapOptions = {
center: _center,
zoom: 7,
mapTypeControl: false,
draggable: _isDraggable,
scrollwheel: false,
streetViewControl: false,
styles: // [{"stylers":[{"visibility":"simplified"}]},{"stylers":[{"color":"#1f2b40"}]},{"featureType":"water","stylers":[{"color":"#131313"},{"lightness":7}]},{"elementType":"labels.text.fill","stylers":[{"visibility":"on"},{"lightness":25}]}]
[{
"featureType": "all",
"elementType": "labels.text.fill",
"stylers": [{"color": "#3b537d"}]
}, {
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": [{"color": "#000000"}, {"lightness": 13}]
}, {
"featureType": "administrative",
"elementType": "geometry.fill",
"stylers": [{"color": "#000000"}]
}, {
"featureType": "administrative",
"elementType": "geometry.stroke",
"stylers": [{"color": "#144b53"}, {"lightness": 14}, {"weight": 1.4}]
}, {
"featureType": "landscape",
"elementType": "all",
"stylers": [{"color": "#1f2b40"}]
}, {
"featureType": "poi",
"elementType": "geometry",
"stylers": [{"color": "#0c4152"}, {"lightness": 5}]
}, {
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [{"color": "#000000"}]
}, {
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [{"color": "#46546d"}, {"lightness": 25}]
}, {
"featureType": "road.arterial",
"elementType": "geometry.fill",
"stylers": [{"color": "#000000"}]
}, {
"featureType": "road.arterial",
"elementType": "geometry.stroke",
"stylers": [{"color": "#0b3d51"}, {"lightness": 16}]
}, {
"featureType": "road.local",
"elementType": "geometry",
"stylers": [{"color": "#000000"}]
}, /*{"featureType":"transit","elementType":"all","stylers":[{"color":"#146474"}]},*/{
"featureType": "water",
"elementType": "all",
"stylers": [{"color": "#021019"}]
}]
};
_map = new google.maps.Map(document.getElementById('map-view'), mapOptions);
// if only 1 point render it on map
if (_points.length == 1) {
addMarker()
}
// if several, render path
if (_points.length > 1) {
addPath()
}
};
var addMarker = function () {
var point = getPoint(_points[0]); // return promise
point.done(function (p) {
var marker = new google.maps.Marker({
position: p,
map: _map,
zIndex: 100,
icon: '/i/ico-mapmarker.png',
title: ''
});
marker.setMap(_map);
_map.setCenter(p);
}).fail(function (message) {
console.error(message);
});
};
var addPath = function () {
// for first and last points generate markers
$.when(getPoint(_points[0]), getPoint(_points[_points.length - 1]))
.done(function (first, last) {
var startMarker = new google.maps.Marker({
position: first,
map: _map,
zIndex: 100,
icon: '/i/start-point.png',
title: ''
});
var endMarker = new google.maps.Marker({
position: last,
map: _map,
zIndex: 100,
icon: '/i/end-point.png',
title: ''
});
startMarker.setMap(_map);
endMarker.setMap(_map);
}).fail(function (message) {
console.error(message);
});
// preprocess all points without deffered object
// in result we will get addresses as is, but coordinates will transform to LatLng
var flightPlanCoordinates = _points.map(function (el) {
return getPoint(el, true);
});
var direction = getDirection(flightPlanCoordinates); // returns promise
var flightPath = new google.maps.Polyline({
path: [],
geodesic: true,
zIndex: 90,
strokeColor: '#80d460',
strokeOpacity: 1.0,
strokeWeight: 4
});
direction.done(function (result) {
// if directions is used, we get all legs (lines, paths), generated by google and draw our own designed lines
if (_useDirectios) {
var legs = result.routes[0].legs;
for (var i = 0; i < legs.length; i++) {
var steps = legs[i].steps;
for (var j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
for (var k = 0; k < nextSegment.length; k++) {
flightPath.getPath().push(nextSegment[k]);
}
}
}
} else {
// else use simple drawing with all initial points we have
// put all promises to array
// it will be arguments for $.when(defPoints[0],defPoints[1]...defPoints[n])
var defPoints = _points.map(function (el) {
return getPoint(el);
});
// "apply" for possibility pass many arguments to function as array
$.when.apply(null, defPoints)
.done(function () { // defer returns as many arguments as $.when() got
flightPath.setPath(arguments);
}).fail(function (message) {
console.error(message);
});
}
// zooming map, that we see all path
var bounds = result.routes[0].bounds;
_map.fitBounds(bounds);
_map.setCenter(bounds.getCenter());
flightPath.setMap(_map);
}).fail(function (message) {
console.error(message);
});
};
var addPoints = function (json) {
/*
* JSON look like this
* [
* {"MIGX_id":"1","point":"Астана, Казахстан"},
* {"MIGX_id":"2","point":"Ерейментау, Казахстан, Акмолинская область"},
* {"MIGX_id":"3","point":"поселок Шидерты, Казахстан, Павлодарская область, городской акимат Екибастуз"}
* ]
* */
if (json.length)
_points = JSON.parse(json).map(function (point) {
return point.point;
});
// now it simple flat array
};
var getPoint = function (point, nodef) {
var deferred = $.Deferred();
var pointsParset = point.split(","); // try split string, if it has LatLng "51.6935438,74.5552978"
var points = {
lat: parseFloat(pointsParset[0]),
lng: parseFloat(pointsParset[1])
};
// if after parseFloat it is Float between -180 and 180
// then return LatLng as promise
if (
(!isNaN(points.lat) && points.lat <= 180 && points.lat >= -180) &&
(!isNaN(points.lng) && points.lng <= 180 && points.lng >= -180)
) {
if (nodef) return points;
deferred.resolve(points);
return deferred.promise();
} else {
// else if it address string, try resolve it with google.maps.Geocoder()
if (nodef) return point;
return getPointByAddress(point); // returns promise
}
};
var getPointByAddress = function (address) {
var deferred = $.Deferred();
// cache for geodata
if (address in _cache) {
deferred.resolve(_cache[address]);
return deferred.promise()
}
var geocoder = new google.maps.Geocoder();
if (geocoder) {
geocoder.geocode({'address': address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
deferred.resolve(results[0].geometry.location);
_cache[address] = results[0].geometry.location;
} else {
deferred.reject("No results found");
}
} else {
deferred.reject("Geocode was not successful for the following reason: " + status);
}
});
} else {
deferred.reject('Geocoder don\'t exists')
}
return deferred.promise()
};
var getDirection = function (ponts) {
var directionsService = new google.maps.DirectionsService();
var deferred = $.Deferred();
var request = {
origin: ponts[0],
destination: ponts[ponts.length - 1],
travelMode: google.maps.TravelMode.DRIVING,
};
// if we have > 2 points, all points except first and last mast be in waypoints object
if (ponts.length > 2) {
var waypoints = ponts.slice(1, -1).map(function (p) {
return {
location: p,
stopover: false
};
});
request.waypoints = waypoints;
}
directionsService.route(request, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
deferred.resolve(result);
} else {
deferred.reject("Directions Service was not successful for the following reason: " + status);
}
});
return deferred.promise()
};
// prototype
module.prototype = {
//addPoints: addPoints
};
// return module
return module;
})();
// usage
$(function(){
new ProjectMap('[{"MIGX_id":"1","point":"Астана, Казахстан"},{"MIGX_id":"2","point":"Ерейментау, Казахстан, Акмолинская область"},{"MIGX_id":"3","point":"поселок Шидерты, Казахстан, Павлодарская область, городской акимат Екибастуз"}]');
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment