Good morning. I am trying to get my map to show a route based on average traffic conditions on a Monday morning at 11:00am EST. I can do this with the calculateRoute service by appending the following to the service URL:
&depart=".date('Y-m-d', strtotime('monday this week'))."T11:00:00-05
I use this to gather my turn by turn directions, but I would also like the visual route line on the map to reflect this as well. I am very new to JS so please forgive my code, I mainly used the canned demo scripts and modified them to do what I needed. Below is the code for my map. This does also use PHP in the code, but mainly for SQL data and grabbing GET data.
<script>
// Initialize the platform object:
var platform = new H.service.Platform({
'app_id': 'MY APP ID',
'app_code': 'MY APP CODE'
});
// Obtain the default map types from the platform object
var maptypes = platform.createDefaultLayers();
// Obtain the default map types from the platform object:
var defaultLayers = platform.createDefaultLayers();
// Instantiate (and display) a map object:
var map = new H.Map(
document.getElementById('mapContainer'),
defaultLayers.normal.traffic,
{
zoom: 10,
center: { lat: 42.3314, lng: -83.0458 }
}
);
// Create the default UI:
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Enable the event system on the map instance:
var mapEvents = new H.mapevents.MapEvents(map);
// Add event listeners:
map.addEventListener('tap', function(evt) {
// Log 'tap' and 'mouse' events:
console.log(evt.type, evt.currentPointer.type);
});
// Instantiate the default behavior, providing the mapEvents object:
var behavior = new H.mapevents.Behavior(mapEvents);
var routingParameters = {
// The routing mode:
'mode': 'fastest;truck;traffic:enabled',
'waypoint0': 'geo!<?PHP echo $_GET['shipFrom']; ?>',
// The end point of the route:
'waypoint1': 'geo!<?PHP echo $geoCode; ?>',
// To retrieve the shape of the route we choose the route
// representation mode 'display'
'representation': 'display'
};
// Define a callback function to process the routing response:
var onResult = function(result) {
var route,
routeShape,
startPoint,
endPoint,
linestring;
if(result.response.route) {
// Pick the first route from the response:
route = result.response.route[0];
// Pick the route's shape:
routeShape = route.shape;
// Create a linestring to use as a point source for the route line
linestring = new H.geo.LineString();
// Push all the points in the shape into the linestring:
routeShape.forEach(function(point) {
var parts = point.split(',');
linestring.pushLatLngAlt(parts[0], parts[1]);
});
// Retrieve the mapped positions of the requested waypoints:
startPoint = route.waypoint[0].mappedPosition;
endPoint = route.waypoint[1].mappedPosition;
// Create a polyline to display the route
routeLine = new H.map.Polyline(linestring, {
style: { lineWidth: 10 },
arrows: { fillColor: 'white', frequency: 2, width: 0.8, length: 0.7 }
});
// Create a marker for the start point:
var startMarker = new H.map.Marker({
lat: startPoint.latitude,
lng: startPoint.longitude
});
// Create a marker for the end point:
var endMarker = new H.map.Marker({
lat: endPoint.latitude,
lng: endPoint.longitude
});
// Add the route polyline and the two markers to the map:
map.addObjects([routeLine, startMarker, endMarker]);
// Set the map's viewport to make the whole route visible:
map.setViewBounds(routeLine.getBounds());
}
};
// Get an instance of the routing service:
var router = platform.getRoutingService();
// Call calculateRoute() with the routing parameters,
// the callback and an error callback function (called if a
// communication error occurs):
router.calculateRoute(routingParameters, onResult,
function(error) {
alert(error.message);
});
</script>
You could just add the departure parameter in the routingParameters used in the above shared javascript code
var routingParameters = {
// The routing mode:
'mode': 'fastest;truck;traffic:enabled',
'waypoint0': 'geo!<?PHP echo $_GET['shipFrom']; ?>',
// The end point of the route:
'waypoint1': 'geo!<?PHP echo $geoCode; ?>',
// To retrieve the shape of the route we choose the route
// representation mode 'display'
'representation': 'display',
//departure time
'departure' : '2018-10-22T11:00:00-05'
};
Related
We're currently getting routes using the v8 endpoint seen at:
https://developer.here.com/documentation/routing-api/api-reference-swagger.html
For each route, we'd like to get all administrative divisions/regions/boundaries such as states, counties, cities, etc (for United States). How might we go about doing this?
We've thought about using HERE polylines in tandem with OpenStreetMap but I would hope that there might already be a solution for this?
you can use map tile api to to show map in the background as shown in this sample example : https://demo.support.here.com/examples/v3.1/simple_routing
(function(){
/*
author
(C) HERE 2019
*/
var mapContainer = document.getElementById('mapContainer');
// check if the site was loaded via secure connection
var secure = (location.protocol === 'https:') ? true : false;
var platform = new H.service.Platform({
useHTTPS: secure,
apikey: api_key
}),
defaultLayers = platform.createDefaultLayers(),
router = platform.getRoutingService(),
map = new H.Map(mapContainer, defaultLayers.vector.normal.map,
{
center: center,
zoom: zoom,
pixelRatio: window.devicePixelRatio || 1
}
);
// Do not draw under control panel
map.getViewPort().setPadding(0, 0, 0, $('.ctrl-panel').width());
// add behavior control
new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Enable the default UI
var ui = H.ui.UI.createDefault(map, defaultLayers);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
function calculateRoute()
{
var calculateRouteParams = {
'waypoint0' : '52.516222,13.388900',
'waypoint1' : '52.517175,13.395129',
'mode': 'fastest;car;traffic:disabled',
'representation': 'display'
},
onResult = function(result) {
var lineString = new H.geo.LineString(),
routeShape = result.response.route[0].shape,
polyline;
routeShape.forEach(function(point) {
var parts = point.split(',');
lineString.pushLatLngAlt(parts[0], parts[1]);
});
var polyline = new H.map.Polyline(lineString,
{
style:
{
lineWidth: 10,
strokeColor: "rgba(0, 128, 0, 0.7)"
}
});
map.addObject(polyline);
map.getViewModel().setLookAtData({
tilt: 45,
bounds: polyline.getBoundingBox()
});
},
onError = function(error) {
console.log(error);
}
router.calculateRoute(calculateRouteParams, onResult, onError);
}
var displayReady = function(e)
{
map.removeEventListener("mapviewchangeend", displayReady);
calculateRoute();
};
map.addEventListener("mapviewchangeend", displayReady);
})
I have articles which i'm getting from my API. My API lists them correctly when i go to http://localhost:60367/api/article/ and gets the correct data correctly for a single item when i go to http://localhost:60367/api/article/1
Using angular, how get the data for one of these articles by it's id so that if i go to my angular app and click to http://localhost:60300/perspectives/1/ I get the data of that one item. ( fyi, When i go to the index http://localhost:60300/perspectives/ I get the data accordingly. )
Please assist, my app.js file is below:
var url = "http://localhost:60367/api/article";
var modules = ['ngRoute', 'ngSanitize'];
var App = angular.module("App", modules);
// Route providers
App.config(function ($routeProvider, $locationProvider) {
$routeProvider
// Get route for perspectives homepage
.when('/', {templateUrl: 'partials/articles-home.html',
controller: ArticleController})
// Get route for perspectives single page
.when("/:id/", {templateUrl: 'partials/articles-single.html',
controller: ArticleController})
.otherwise({ redirectTo : "/"})
// Use the HTML5 History API
$locationProvider.html5Mode({ enabled: true, requireBase: false});
});
// Controller
var ArticleController = function ($scope, $http, $log) {
// For onsuccess, also do console.log for $log property
var onSuccess = function (response) {$scope.articles = response.data;
$log.info(response);};
var onFailure = function (reason) {$scope.error =
reason;$log.info(reason);};
// Get all students and display them in index
var getAllArticles = function () {$http.get(url).then(onSuccess,
onFailure)};
getAllArticles();
// Get single student by Id
//
//
};
App.controller("ArticleController", ArticleController);
SOLUTION:
Ok this is how I solved it, I created a new controller for the single item and wrote it manually like this:
var SingleArticleController = function ($scope, $http, $routeParams) {
$http({
url: "http://localhost:60367/api/article/{id}",
params: { id: $routeParams.id },
method: "get"
})
.then(function (response) {
$scope.article = response.data;
});
};
You'll want to use $routeParams:
What I've outline here will allow you to use the same controller here as that's what you've show in your config. Often-times, you'd assign a separate controller in your route (something like ArticleController, ArticleListController.). If you do that, the same process applies, but you wouldn't need to check if you have an ID parameter.
In your Controller:
// Add $routeParams
.controller('ArticleController', function($scope, $routeParams) {
// Get the id
var id = $routeParams.id;
// Set url based on whether or not you have an ID
var fullUrl = id ? url + '/' + id : url;
var getAllArticles = function() {
$http.get(fullUrl).then(onSuccess,
onFailure)
};
})
Currently i am able to display 3 route of 3 drivers respectively(one for each) on a single Gmap.
Now, I wish to show route of 'n' number of drivers (single route for each driver)on Gmap. Its a case of dynamic drivers. I can get data from db for 'n' number of drivers that i need to display on a single map.
My Code is below for single driver please help me for dynamic craetion of routes:
var lat_lng1 = [];
var latlngbounds1 = "";
lat_lng1 = new Array();
var value1 = markers1.length;
//Intialize the Path Array
var path1 = new google.maps.MVCArray();
//Intialize the Direction Service
var service1 = new google.maps.DirectionsService();
var lineSymbol1 = { path1: google.maps.SymbolPath.CIRCLE };
//Set the Path Stroke Color
for (i = 0; i < markers1.length; i++) {
var data1 = markers1[i]
var myLatlng1 = new google.maps.LatLng(data1.lat, data1.lng);
lat_lng1.push(myLatlng1);
var marker1 = new google.maps.Marker({position: myLatlng1,map: map,icon: icon1});
(function (marker1, data1) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker1, "click", function (e) {
if (i == 0){
infoWindow.setContent(data1.Person);infoWindow.open(map, marker1);}
if(i=(markers2.length -1)){
infoWindow.setContent(data1.Person);infoWindow.open(map, marker1);}
else{
infoWindow.setContent(data1.Title);
infoWindow.open(map, marker1);}
});
})(marker1, data1);
}
poly = new google.maps.Polyline({
// path: lineCoordinates,
strokeColor: '#BC456F',
icons: [{
icon: {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,strokeColor: '#009900',fillColor: '#009900',fillOpacity: 1},
repeat: '100px',
path1: []
}],
map: map
});
well I solved this issue the very next day by calling ajax loops by driver id
I have a map thats populated with markers of places from a fusion table. I'm taking the users location and displaying a circle of radius 10 miles from their location. Here is my code - http://connormccarra.com/sandbox/map/. How can I use the api to count the number of markers bound by the circle and output that number in the footer?
Cheers!
Relevant code:
var map;
function Initialize() {
var MapOptions = {
zoom: 7,
center: new google.maps.LatLng(53.4125694, -8.245014),
mapTypeId: google.maps.MapTypeId.ROADMAP,
sensor: true
};
map = new google.maps.Map(document.getElementById("map_canvas"), MapOptions);
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Address',
from: '1OPU6utSjRYwJSFK-EXdaGmt2KgLTq2loVIjS3AA'
}
});
layer.setMap(map);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var marker = new google.maps.Marker({
map: map,
position: pos,
content: 'You are here!'
});
// Add circle overlay and bind to marker
var circle = new google.maps.Circle({
map: map,
radius: 16093, // 10 miles in metres
fillColor: '#AA0000'
});
circle.bindTo('center', marker, 'position');
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var count = mgr.getMarkerCount(circle);
document.getElementById("Address").innerHTML += count + "<BR>";
google.maps.event.addDomListener(window, 'load', initialize);
//Maps API loaded, now load customizations
var element = document.createElement('script');
element.src = 'template.js';
element.type = 'text/javascript';
var scripts = document.getElementsByTagName('script')[0];
scripts.parentNode.insertBefore(element, scripts);
}
The markers created by a FusionTableLayer are not real markers, there is no way to get them as a kind of list to filter them(you can't get any details for the markers, except you click them).
But you may request the FusionTableAPI with a spatial condition(via AJAX, jsonp is supported).
The syntax for the query:
SELECT COUNT() from tableId
WHERE ST_INTERSECTS('Address',CIRCLE(LATLNG(lat,lng),10000))
How to send a query : https://developers.google.com/fusiontables/docs/v1/sql-reference
Demo(using data of another FusionTable because your table is protected):
http://jsfiddle.net/doktormolle/bAtgf/
Simplest way: use the geometry library computeDistanceBetween method. If the distance from the user's location is less than 10 miles, the marker is in the circle.
I suggest you first fetch all the coordinates of your FusionTablesLayer.
Here is an example which was used in the sidebar
http://www.geocodezip.com/v3_FusionTables_AfricaMap_kml_sidebar.html
Then using a loop statement you can use the computeDistanceBetween function.
Detect If Marker is Within Circle Overlay
I am running multiple ajax calls to download a large number of google maps icons. When I try to increment the Marker Clusterer, however, the map clears all markers. I believe this is because I am calling var markerCluster = new MarkerCluster(map); in each AJAX call.
Can anyone tell me how to correctly implement this?
var populateMapByIncident = function(incident, page) {
var run_again = false;
$.getJSON(
"/public_map_ajax_handler",
{"shortname" : incident, "page": page},
function(sites_list) {
if (sites_list.length > 2) {
run_again = true;
}
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(40.6501038, -73.8495823),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var markers = [];
var i = 0;
for (var i = 0; i < sites_list.length; i++) {
var latLng = new google.maps.LatLng(sites_list[i].latitude, sites_list[i].longitude);
var marker = new google.maps.Marker({'position': latLng,
'icon': getMarkerIcon(sites_list[i]),
'site_id': sites_list[i].id,
'case_number': sites_list[i].case_number,
'work_type': sites_list[i].work_type,
'floors_affected': sites_list[i].floors_affected,
'status': sites_list[i].status});
markers.push(marker);
var site_id = sites_list[i].id;
google.maps.event.addListener(marker, "click", function() {
new Messi('<p>Name, Address, Phone Number are removed from the public map</p><p>Details: work type: '
+ this.work_type+ ', floors affected: ' + this.floors_affected + '</p>' + '<p>Status: ' + this.status + '</p>',
{title: 'Case Number: ' + this.case_number, titleClass: 'info',
buttons: [
{id: 0, label: 'Printer Friendly', val: "On the live version, this would send all of this site's data to a printer friendly page." },
{id: 1, label: 'Change Status', val: "On the live version, you would be able to change the site's status here."},
{id: 2, label: 'Edit', val: "On the live version, you would be able to edit the site's info, as new details come in."},
{id: 3, label: 'Claim', val: "On the live version, clicking this button would 'Claim' the site for your organization, letting other organizations know that you intend to work on that site"},
{id: 4, label: 'Close', val: 'None'}], callback: function(val) { if (val != "None") {Messi.alert(val);} }});
});
}
var markerCluster = new MarkerClusterer(map);
markerCluster.addMarkers(markers);
if (run_again == true) {
populateMapByIncident(incident, page + 1, markers);
} else {
markerCluster.addMarkers(markers);
}
}
);
}
I am running multiple ajax calls to download a large number of google maps icons. When I try to increment the Marker Clusterer, however, the map clears all markers. I believe this is because I am calling var markerCluster = new MarkerCluster(map); in each AJAX call.
Can anyone tell me how to correctly implement this?
Don't do that. Create the MarkerClusterer one time in the global scope (outside of any function), and add markers to it when you receive them from the server (assuming you aren't sending any duplicates).
See the documentation
Looks like you are already adding arrays of markers to the MarkerClusterer:
addMarkers(markers:Array., opt_nodraw:boolean) | None | Add an array of markers to the clusterer.
All you really need to do is move where you create the MarkerClusterer to the global scope. One suggestion below.
var markerCluster = new MarkerClusterer(map); // <------------- add this
var populateMapByIncident = function(incident, page) {
var run_again = false;
$.getJSON(
// ----- existing code ------- //
// leave as is
// ----- modification -------- //
// var markerCluster = new MarkerClusterer(map); <----------- remove this
markerCluster.addMarkers(markers);
if (run_again == true) {
populateMapByIncident(incident, page + 1, markers);
} else {
markerCluster.addMarkers(markers);
}