How to add point on polyline somewhere between two vertexes? - google-maps-api-3

The goal is to have an editable polyline with customized markers at every vertex.
As I see Map API V3 does not allows that. So I made editable polyline like this:
let polyline = new self.google.maps.Polyline({
strokeColor: '#000000',
strokeOpacity: 0.3,
strokeWeight: 3,
editable: false,
path: path,
map: self.map
});
polyline.binder = new MVCArrayBinder(polyline.getPath());
let markers = [];
for (let i = 0; i < path.length; i++) {
let marker = this.getBasicMarker(path[i]);
marker.bindTo('position', polyline.binder, i.toString());
markers.push(marker);
}
getBasicMarker(position){
return new this.google.maps.Marker({
position: position,
map: this.map,
icon: {
url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
size: new google.maps.Size(7, 7),
anchor: new google.maps.Point(3.5, 3.5)
},
draggable: true,
visible: false
});
}
function MVCArrayBinder(mvcArray) {
this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function (key) {
if (!isNaN(parseInt(key))) {
return this.array_.getAt(parseInt(key));
} else {
this.array_.get(key);
}
};
MVCArrayBinder.prototype.set = function (key, val) {
if (!isNaN(parseInt(key))) {
this.array_.setAt(parseInt(key), val);
} else {
this.array_.set(key, val);
}
};
Final polyline now looks like this: http://sandbox.rubera.ru/img/2019-05-28_17-04-25.jpg. I can drag any existing point. The polyline updating while dragging the point.
Now I have to add new vertex somewhere between two existing.
This is where I'm stuck.
May be there is another solution how to solve the task?

In case anybody face similar task here is a few modifications to my code posted abowe. That helped me finally solve the problem.
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function (key) {
if (!isNaN(parseInt(key))) {
return this.array_.getAt(parseInt(key));
} else {
this.array_.get(key);
}
};
MVCArrayBinder.prototype.set = function (key, val) {
if (!isNaN(parseInt(key))) {
this.array_.setAt(parseInt(key), val);
} else {
this.array_.set(key, val);
}
};
MVCArrayBinder.prototype.insertAt = function (key, val) {
this.array_.insertAt(key, val);
};
google.maps.event.addListener(this.activePoly, 'click', function (e) {
let path = $this.activePoly.getPath(),
inserted = false;
// find line segment
for (let i = 0; i < path.getLength() - 1, !inserted; i++) {
let tempPoly = new google.maps.Polyline({
path: [path.getAt(i), path.getAt(i + 1)]
});
if (google.maps.geometry.poly.isLocationOnEdge(e.latLng, tempPoly, 10e-2)) {
$this.activeRoute.binder.insertAt(i + 1, e.latLng);
inserted = true;
let marker = $this.getBasicMarker(e.latLng);
marker.setVisible(true);
// Add new marker to array
$this.activeRoute.markers.splice(i + 1, 0, marker);
// Have to rebind all markers
$this.activeRoute.markers.forEach((marker, index) => {
marker.bindTo('position', $this.activeRoute.binder, index.toString());
});
}
}
});
My activeRoute is an object with following structure:
{polyline: polyline, markers: markers, binder: polyline.binder}

Related

Change infowindow marker based on variable in realtime

How do I change the icon of a marker based on if a value is true or false.
I created an if function that checks the value of CameraStatus. I set it to false on default but the marker still won't change to RedStatus. It does change to RedStatus when I try a timer like this:
setTimeout(function () { MiamiMarker.setIcon(RedStatus) }, 10 * 1000);
It doesn't change to RedStatus when I try this:
var CameraStatus = false;
function CheckStatus() {
if (CameraStatus === false) {
MiamiMarker.SetIcon(RedStatus)
}
}
How do I change the marker based on my if function?
Eventually I want to change all my markers with boolean values I get from a home controller. The value of the boolean should decide if the marker has a GreenStats or RedStatus icon. First I'm trying to change one marker based on a hardcoded value. (See code below)
My code:
<script>
var map;
function initMap() {
var CenterLoc = { lat: 51.34, lng: 5.53 };
map = new google.maps.Map(document.getElementById('map'),
{
center: CenterLoc,
disableDefaultUI: true,
zoom: 3,
});
google.maps.event.addDomListener(window, 'load', initMap);
var Miami = { lat: 25.774266, lng: -80.193659 };
var MiamiMarker = new google.maps.Marker
({
position: Miami,
map: map,
icon: GreenStatus
});
//Replace standard google maps markers with colored dots
var GreenStatus = "#ViewBag.GreenStatus";
var OrangeStatus = "#ViewBag.OrangeStatus";
var RedStatus = "#ViewBag.RedStatus";
var CameraStatus = false;
function CheckStatus() {
if (CameraStatus === false) {
MiamiMarker.SetIcon(RedStatus)
}
}
var MiamiInfoCard = new google.maps.InfoWindow
({
content: '<div id="map-dialog"><h3>Miami</h3></div>'
});
MiamiMarker.addListener('click', function () {
MiamiInfoCard.open(map, MiamiMarker);
});
var position = new google.maps.LatLng(52.2305, 5.9924);
}
</script>
You can use an if else statement to change your Icon. Please note that it is .setIcon() and not *.SetIcon() just like in your code.
if (CameraStatus == false) {
MiamiMarker.setIcon(RedStatus)
} else {
MiamiMarker.setIcon(GreenStatus)
}
You can check this sample code that reproduces what you want in your use-case.
I used a toggle switch to set values for CameraStatus and call the CheckStatus() function passing the variables CameraStatus and MiamiMarker to be processed in the function.
var switchStatus = document.getElementById("mySwitch");
var CameraStatus;
switchStatus.addEventListener('change', function() {
if (switchStatus.checked) {
CameraStatus = false;
} else {
CameraStatus = true;
}
CheckStatus(CameraStatus, MiamiMarker);
});
I put the CheckStatus() function outside the initMap() function and passed the CameraStatus and MiamiMarker to change the marker's icon base on the value of CameraStatus.
function CheckStatus(CameraStatus, MiamiMarker) {
if (CameraStatus == false) {
MiamiMarker.setIcon(RedStatus)
} else {
MiamiMarker.setIcon(GreenStatus)
}
Hope this helps!

A-FRAME Extend component

Consider this:
<a-entity id="player">
<a-entity id="camera" camera look-controls></a-entity>
<a-entity id="leftHand" oculus-touch-controls="hand: left"></a-entity>
<a-entity id="rightHand" oculus-touch-controls="hand: right"></a-entity>
</a-entity>
If I want to move my player through the scene, I would add wasd-controls to #player. Doing that, disregards the orientation of the head (camera): W always moves "north", wherever you are looking at. If I add wasd-controls to #camera, the head moves correctly but the controllers are left behind.
So I thought of creating a custom wasd-controls, but I am unable to extend that component. I have been successful copying and pasting all the code, but that is very nasty.
This did not work: AFrame extend component and override.
Any idea?
my-wasd-controls.js
var KEYCODE_TO_CODE = require('aframe/src/constants').keyboardevent.KEYCODE_TO_CODE;
var AFRAME = require('aframe');
var THREE = require('aframe/src/lib/three');
var utils = require('aframe/src/utils');
var bind = utils.bind;
var shouldCaptureKeyEvent = utils.shouldCaptureKeyEvent;
var CLAMP_VELOCITY = 0.00001;
var MAX_DELTA = 0.2;
var KEYS = [
'KeyW', 'KeyA', 'KeyS', 'KeyD',
'ArrowUp', 'ArrowLeft', 'ArrowRight', 'ArrowDown'
];
/**
* WASD component to control entities using WASD keys.
*/
module.exports.Component = AFRAME.registerComponent('my-wasd-controls', {
schema: {
acceleration: {default: 65},
adAxis: {default: 'x', oneOf: ['x', 'y', 'z']},
adEnabled: {default: true},
adInverted: {default: false},
easing: {default: 20},
enabled: {default: true},
fly: {default: false},
head: {type: 'selector'},
wsAxis: {default: 'z', oneOf: ['x', 'y', 'z']},
wsEnabled: {default: true},
wsInverted: {default: false}
},
init: function () {
// To keep track of the pressed keys.
this.keys = {};
this.position = {};
this.velocity = new THREE.Vector3();
// Bind methods and add event listeners.
this.onBlur = bind(this.onBlur, this);
this.onFocus = bind(this.onFocus, this);
this.onKeyDown = bind(this.onKeyDown, this);
this.onKeyUp = bind(this.onKeyUp, this);
this.onVisibilityChange = bind(this.onVisibilityChange, this);
this.attachVisibilityEventListeners();
},
tick: function (time, delta) {
var currentPosition;
var data = this.data;
var el = this.el;
var movementVector;
var position = this.position;
var velocity = this.velocity;
if (!velocity[data.adAxis] && !velocity[data.wsAxis] &&
isEmptyObject(this.keys)) { return; }
// Update velocity.
delta = delta / 1000;
this.updateVelocity(delta);
if (!velocity[data.adAxis] && !velocity[data.wsAxis]) { return; }
// Get movement vector and translate position.
currentPosition = el.getAttribute('position');
movementVector = this.getMovementVector(delta);
position.x = currentPosition.x + movementVector.x;
position.y = currentPosition.y + movementVector.y;
position.z = currentPosition.z + movementVector.z;
el.setAttribute('position', position);
},
remove: function () {
this.removeKeyEventListeners();
this.removeVisibilityEventListeners();
},
play: function () {
this.attachKeyEventListeners();
},
pause: function () {
this.keys = {};
this.removeKeyEventListeners();
},
updateVelocity: function (delta) {
var acceleration;
var adAxis;
var adSign;
var data = this.data;
var keys = this.keys;
var velocity = this.velocity;
var wsAxis;
var wsSign;
adAxis = data.adAxis;
wsAxis = data.wsAxis;
// If FPS too low, reset velocity.
if (delta > MAX_DELTA) {
velocity[adAxis] = 0;
velocity[wsAxis] = 0;
return;
}
// Decay velocity.
if (velocity[adAxis] !== 0) {
velocity[adAxis] -= velocity[adAxis] * data.easing * delta;
}
if (velocity[wsAxis] !== 0) {
velocity[wsAxis] -= velocity[wsAxis] * data.easing * delta;
}
// Clamp velocity easing.
if (Math.abs(velocity[adAxis]) < CLAMP_VELOCITY) { velocity[adAxis] = 0; }
if (Math.abs(velocity[wsAxis]) < CLAMP_VELOCITY) { velocity[wsAxis] = 0; }
if (!data.enabled) { return; }
// Update velocity using keys pressed.
acceleration = data.acceleration;
if (data.adEnabled) {
adSign = data.adInverted ? -1 : 1;
if (keys.KeyA || keys.ArrowLeft) { velocity[adAxis] -= adSign * acceleration * delta; }
if (keys.KeyD || keys.ArrowRight) { velocity[adAxis] += adSign * acceleration * delta; }
}
if (data.wsEnabled) {
wsSign = data.wsInverted ? -1 : 1;
if (keys.KeyW || keys.ArrowUp) { velocity[wsAxis] -= wsSign * acceleration * delta; }
if (keys.KeyS || keys.ArrowDown) { velocity[wsAxis] += wsSign * acceleration * delta; }
}
},
getMovementVector: (function () {
var directionVector = new THREE.Vector3(0, 0, 0);
var rotationEuler = new THREE.Euler(0, 0, 0, 'YXZ');
return function (delta) {
var rotation = (this.data.head || this.el).getAttribute('rotation');
var velocity = this.velocity;
var xRotation;
directionVector.copy(velocity);
directionVector.multiplyScalar(delta);
// Absolute.
if (!rotation) { return directionVector; }
xRotation = this.data.fly ? rotation.x : 0;
// Transform direction relative to heading.
rotationEuler.set(THREE.Math.degToRad(xRotation), THREE.Math.degToRad(rotation.y), 0);
directionVector.applyEuler(rotationEuler);
return directionVector;
};
})(),
attachVisibilityEventListeners: function () {
window.addEventListener('blur', this.onBlur);
window.addEventListener('focus', this.onFocus);
document.addEventListener('visibilitychange', this.onVisibilityChange);
},
removeVisibilityEventListeners: function () {
window.removeEventListener('blur', this.onBlur);
window.removeEventListener('focus', this.onFocus);
document.removeEventListener('visibilitychange', this.onVisibilityChange);
},
attachKeyEventListeners: function () {
window.addEventListener('keydown', this.onKeyDown);
window.addEventListener('keyup', this.onKeyUp);
},
removeKeyEventListeners: function () {
window.removeEventListener('keydown', this.onKeyDown);
window.removeEventListener('keyup', this.onKeyUp);
},
onBlur: function () {
this.pause();
},
onFocus: function () {
this.play();
},
onVisibilityChange: function () {
if (document.hidden) {
this.onBlur();
} else {
this.onFocus();
}
},
onKeyDown: function (event) {
var code;
if (!shouldCaptureKeyEvent(event)) { return; }
code = event.code || KEYCODE_TO_CODE[event.keyCode];
if (KEYS.indexOf(code) !== -1) { this.keys[code] = true; }
},
onKeyUp: function (event) {
var code;
code = event.code || KEYCODE_TO_CODE[event.keyCode];
delete this.keys[code];
}
});
function isEmptyObject (keys) {
var key;
for (key in keys) { return false; }
return true;
}
I would still recommend copy and pasting it. If you ever upgrade A-Frame later, and wasd-controls changes, your extensions will probably break.
Changing the prototype should work (e.g., AFRAME.components['wasd-controls'].Component.prototype.foo = () => {}). The prototype methods are writable.
Another alternative is to overwrite the method on the component instance. el.components['wasd-controls'].foo = () => {}.

How to show dynamically multiple popup in openlayers 3 map

Can anyone tell me how to show all popup of markers in openlayers 3 map. I searched many sites but couldn't get any answer please anyone know about this then help me
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure',
crossOrigin: 'anonymous'
})
})
],
overlays: [overlay],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([0, 50]),
zoom: 2
})
});
var vectorSource = new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([16.37, 48.2])),
name: 'London'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-0.13, 51.51])),
name: 'NY'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([30.69, 55.21])),
name: 'Paris'
})
]
});
var markers = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
image: new ol.style.Icon({
src: '//openlayers.org/en/v3.12.1/examples/data/icon.png',
anchor: [0.5, 1]
})
})
});
map.addLayer(markers);
function showpopup(){
// For showing popups on Map
var arrayData = [1];
showInfoOnMap(map,arrayData,1);
function showInfoOnMap(map, arrayData, flag) {
var flag = 'show';
var extent = map.getView().calculateExtent(map.getSize());
var id = 0;
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'center'
});
map.addOverlay(popup);
if (arrayData != null && arrayData.length > 0) {
arrayData.forEach(function(vectorSource) {
/* logMessage('vectorSource >> ' + vectorSource); */
if (vectorSource != null && markers.getSource().getFeatures() != null && markers.getSource().getFeatures().length > 0) {
markers.getSource().forEachFeatureInExtent(extent, function(feature) {
/* logMessage('vectorSource feature >> ' + feature); */
console.log("vectorSource feature >> " + markers.getSource().getFeatures());
if (flag == 'show') {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
/* var prop;
var vyprop = ""; */
$(element).popover({
'position': 'center',
'placement': 'top',
'template':'<div class="popover"><div class="popover-content"></div></div>',
'html': true,
'content': function() {
var string = [];
var st = feature.U.name;
if (st != null && st.length > 0) {
var arrayLength = 1;
string = "<table>";
string += '<tr><td>' + st + "</table>";
}
return string;
}
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
}
});
}
};
}
I used this code in my file but it show only one popup on all markers please someone tell me how to show all markers popup simultaneously.
I'm not sure exactly what you're trying to show in your popups, but I would probably try this approach. This extends the ol.Overlay class, allowing you to get the map object and attach a listener which you can use to grab the feature that was clicked. Is this what you're trying to accomplish?
function PopupOverlay() {
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element
});
}
ol.inherits(PopupOverlay, ol.Overlay);
PopupOverlay.prototype.setMap = function (map) {
var self = this;
map.on('singleclick', function (e) {
map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
ol.Overlay.prototype.setPosition.call(self, feature.getGeometry().getCoordinates());
var el = self.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return feature.get('name');
};
$(el).popover('show');
});
});
ol.Overlay.prototype.setMap.call(this, map);
};
Check out this example
So after your comment, I see what you're trying to do now. I would say that you want to take the same basic approach, make a class that overrides ol.Overlay, but this time just loop through all the features, creating an overlay for each feature.
This Updated Example
function PopoverOverlay(feature, map) {
this.feature = feature;
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element,
map: map
});
};
ol.inherits(PopoverOverlay, ol.Overlay);
PopoverOverlay.prototype.togglePopover = function () {
ol.Overlay.prototype.setPosition.call(this, this.feature.getGeometry().getCoordinates());
var self = this;
var el = this.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return self.feature.get('name');
};
$(el).popover('toggle');
};
// create overlays for each feature
var overlays = (function createOverlays () {
var popupOverlays = [];
vectorSource.getFeatures().forEach(function (feature) {
var overlay = new PopoverOverlay(feature, map);
popupOverlays.push(overlay);
map.addOverlay(overlay);
});
return popupOverlays;
})();
// on click, toggle the popovers
map.on('singleclick', function () {
for(var i in overlays) {
overlays[i].togglePopover();
}
});
Now when you click anywhere on the map, it should call the togglePopover method and toggle the popover on the individual element.

How to draw different coloured polylines with direction service with snap to road feature

I am trying to render bus routes of bangalore city with snap to road feature provided by google api. If I just render single route, it is visible with the colour I mention for stroke color property of polyline.If the route is pretty long, then I am splitting the route into multiple paths for that route. But, when I add the second route, a polyline from the end of first route to the start of second route is drawn. I am not able to figure out, where I am going wrong. Any help is deeply appreciated. Please find the javascript code of the same.
<script type="text/javascript">
var infoWindow = new google.maps.InfoWindow();
var routePath;
var OrgDest;
var OrgDestpoints;
var wp;
var waypts;
var traceroutePath;
var service;
var map;
var marker, markloc;
var markers = [];
var orgdest = {"1": [[12.9197565816171, 77.5923588994416,12.95719452, 77.56829549],[12.95719452, 77.56829549,12.98997477, 77.57209867],[12.98997477, 77.57209867,13.02311, 77.55029]],"KHC": [[12.97466107, 77.58199613,12.97466107, 77.58199613]]};
var waypoints = {"1":[[12.92268932, 77.59338455,12.92318598, 77.58877168,12.9279596, 77.58760419,12.93610683, 77.58392363,12.93672057, 77.57217014,12.93956243, 77.57215225,12.94189, 77.57358,12.94574241, 77.57070059],[12.95850855, 77.57402561,12.96161187, 77.57527904,12.96366, 77.56843,12.96811874, 77.56800682,12.97736, 77.57074,12.98997477, 77.57209867],[12.98997477, 77.57209867,12.99789013, 77.57130999,13.00908169, 77.5710476,13.01742075, 77.55707759]],"KHC": [[12.98420536, 77.59761828,12.98368012, 77.6035693]]};
var routeColors = {"1": "#FF00FF","KHC": "#800000"};
var routeNames = ["1","KHC"];
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(12.9536775, 77.5883784),
zoom: 12
};
map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
//directionsDisplay.setMap(map);
var routeInfoWindow = new google.maps.InfoWindow({ // this info window shows the route name when the mouse hovers over a route line
disableAutoPan: true
});
for (var i = 0; i < routeNames.length; i++) { // loop over each route
var routeName = routeNames[i];
for (var j = 0; j < orgdest[routeName].length; j++) { // loop over each path on the route
OrgDest = orgdest[routeName][j];
OrgDestpoints = []
for (var k = 0; k < OrgDest.length; k += 2) { // loop over each point in the path
OrgDestpoints.push(new google.maps.LatLng(OrgDest[k], OrgDest[k+1]));
}
waypts = [];
if(waypoints[routeName].length > 0)
{
wp = waypoints[routeName][j];
for (var k = 0; k < wp.length; k += 2) { // loop over each waypoints in the path
waypts.push(
{location:new google.maps.LatLng(wp[k], wp[k+1]),
stopover:true
});
}
}
if(j>0)// & (j!=(orgdest[routeName].length)))
traceroutePath.setMap(null); //clearing previously rendered map
if(i>0 & j==0)
{
traceroutePath.setMap(null); //clearing previously rendered map
}
routePath = OrgDestpoints;
traceroutePath = new google.maps.Polyline({
path: routePath,
strokeColor: routeColors[routeName],
strokeOpacity: 1.0,
strokeWeight: 2
});
service = new google.maps.DirectionsService(),traceroutePath,snap_path=[];
traceroutePath.setMap(map);
for(z=0;z<routePath.length-1;z++){
service.route({origin: routePath[z],destination: routePath[z+1],
travelMode: google.maps.DirectionsTravelMode.DRIVING,
waypoints: waypts},
function(result, status) {
if(status == google.maps.DirectionsStatus.OK) {
snap_path = snap_path.concat(result.routes[0].overview_path);
alert(result.routes[0].legs[0].start_location)
traceroutePath.setPath(snap_path);
} else alert("Directions request failed: "+status);
});
}
} //end of j for loop; paths to form a route
}//end of i for loop; all routes
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You have two issues that are causing the issue.
the code is concatenating the paths from the directions requests together, that is an issue because:
a. the directions service is asynchronous, the routes may come back in a different order than you send them (unless you send them one by one).
b. the routes requested are not continuous.
for (z = 0; z < routePath.length - 1; z++) {
service.route({
origin: routePath[z],
destination: routePath[z + 1],
travelMode: google.maps.DirectionsTravelMode.DRIVING,
waypoints: waypts
},
function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
var snap_path = result.routes[0].overview_path;
var traceroutePath = new google.maps.Polyline({
strokeColor: routeColors[routeName],
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
traceroutePath.setPath(snap_path);
} else alert("Directions request failed: " + status);
});
proof of concept fiddle
code snippet:
var infoWindow = new google.maps.InfoWindow();
var routePath;
var OrgDest;
var OrgDestpoints;
var wp;
var waypts;
var traceroutePath;
var service;
var map;
var marker, markloc;
var markers = [];
var orgdest = {
"1": [
[12.9197565816171, 77.5923588994416, 12.95719452, 77.56829549],
[12.95719452, 77.56829549, 12.98997477, 77.57209867],
[12.98997477, 77.57209867, 13.02311, 77.55029]
],
"KHC": [
[12.97466107, 77.58199613, 12.97466107, 77.58199613]
]
};
var waypoints = {
"1": [
[12.92268932, 77.59338455, 12.92318598, 77.58877168, 12.9279596, 77.58760419, 12.93610683, 77.58392363, 12.93672057, 77.57217014, 12.93956243, 77.57215225, 12.94189, 77.57358, 12.94574241, 77.57070059],
[12.95850855, 77.57402561, 12.96161187, 77.57527904, 12.96366, 77.56843, 12.96811874, 77.56800682, 12.97736, 77.57074, 12.98997477, 77.57209867],
[12.98997477, 77.57209867, 12.99789013, 77.57130999, 13.00908169, 77.5710476, 13.01742075, 77.55707759]
],
"KHC": [
[12.98420536, 77.59761828, 12.98368012, 77.6035693]
]
};
var routeColors = {
"1": "#FF00FF",
"KHC": "#800000"
};
var routeNames = ["1", "KHC"];
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(12.9536775, 77.5883784),
zoom: 12
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var routeInfoWindow = new google.maps.InfoWindow({ // this info window shows the route name when the mouse hovers over a route line
disableAutoPan: true
});
for (var i = 0; i < routeNames.length; i++) { // loop over each route
var routeName = routeNames[i];
for (var j = 0; j < orgdest[routeName].length; j++) { // loop over each path on the route
OrgDest = orgdest[routeName][j];
OrgDestpoints = []
for (var k = 0; k < OrgDest.length; k += 2) { // loop over each point in the path
OrgDestpoints.push(new google.maps.LatLng(OrgDest[k], OrgDest[k + 1]));
}
waypts = [];
if (waypoints[routeName].length > 0) {
wp = waypoints[routeName][j];
for (var k = 0; k < wp.length; k += 2) { // loop over each waypoints in the path
waypts.push({
location: new google.maps.LatLng(wp[k], wp[k + 1]),
stopover: true
});
}
}
if (j > 0) // & (j!=(orgdest[routeName].length)))
traceroutePath.setMap(null); //clearing previously rendered map
if (i > 0 & j == 0) {
traceroutePath.setMap(null); //clearing previously rendered map
}
routePath = OrgDestpoints;
traceroutePath = new google.maps.Polyline({
path: routePath,
strokeColor: routeColors[routeName],
strokeOpacity: 1.0,
strokeWeight: 2
});
service = new google.maps.DirectionsService(), traceroutePath, snap_path = [];
traceroutePath.setMap(map);
for (z = 0; z < routePath.length - 1; z++) {
service.route({
origin: routePath[z],
destination: routePath[z + 1],
travelMode: google.maps.DirectionsTravelMode.DRIVING,
waypoints: waypts
},
function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
var snap_path = result.routes[0].overview_path;
var traceroutePath = new google.maps.Polyline({
strokeColor: routeColors[routeName],
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
traceroutePath.setPath(snap_path);
} else alert("Directions request failed: " + status);
});
}
} //end of j for loop; paths to form a route
} //end of i for loop; all routes
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>

How to dynamically add data to google maps API?

I have got a map that I want to have a feed of lat/long data getting pushed to the map data array. I have the function to get the data, but am having trouble getting that to be usable in the map data array.
The idea is to have a new marker drop in when a new coordinate is added to the array. Any ideas? Thanks in advance!
var ID='0';
var DATA=[];
function getData(){
var url = 'http://us7.fieldagent.net/api/newResponses/';
//url = 'http://us7.fieldagent.net/api/newResponses/;
$.post(url,{'id':ID},function(data){
if(data.status_id == 0){
ID = data.id;
console.log('Last Id: '+data.id);
var new_data = data.responses;
var count = 0
$.each(new_data,function(i,v){
count += 1;
var coord = 'new google.maps.LatLng('+v.lat+','+v.lon+'),';
DATA.push(coord);
})
console.log('Added '+count+' responses..')
}
});
}
$(document).ready(function(){
getData();
setInterval(getData,20*1000);
});
function drop() {
for (var i = 0; i < DATA.length; i++) {
setTimeout(function() {
addMarker();
}, i * 500);
}
}
function addMarker(){
markers.push(new google.maps.Marker({
position: DATA[iterator],
map: map,
draggable: false,
icon: 'fatie.svg',
animation: google.maps.Animation.DROP
}));
iterator++;
}
You need to actually add the item to the map. Right now, you're only adding an item to your DATA array. You need to call addMarker with the new data as well.
You seem to want to add these markers to the map at an interval so they drop onto the map over time, while also being able to query for new markers from your server.
Try code like this:
var ID='0';
var DATA=[];
function getData(){
var url = 'http://us7.fieldagent.net/api/newResponses/';
$.post(url,{'id':ID},function(data){
if(data.status_id == 0){
ID = data.id;
console.log('Last Id: '+data.id);
var new_data = data.responses;
var count = 0
$.each(new_data,function(i,v){
count += 1;
var coord = 'new google.maps.LatLng('+v.lat+','+v.lon+'),';
DATA.push(coord);
});
console.log('Added '+count+' responses..');
if (count > 0) addMarker(); //call addMarker if there are new markers
}
});
}
$(document).ready(function(){
getData();
setInterval(getData,20*1000);
});
function addMarker(){
if (DATA.length == 0) return; //exit if DATA is empty
markers.push(new google.maps.Marker({
position: DATA.shift(), //take the first item in DATA
map: map,
draggable: false,
icon: 'fatie.svg',
animation: google.maps.Animation.DROP
}));
if (DATA.length > 0) setTimeout(addMarker, 500); //call again if needed
}
Create a Method which does two things.
Add to the Array
Add the Item to the map

Resources