Using dynamic markers in a Leaflet map - javascript

I'm working on a dynamic mapping application that receives a series of data as JSON and then converts the data to a map point with a pop up in Leaflet.
The JSON data looks like this:
{
"unit":"90",
"latitude":36.120915,
"longitude":-97.0633733,
"velocity":0.022,
"heading":102.9,
"timestamp":"Wed, 23 Nov 2011 20:00:28 GMT"
}
I have a listener setup to receive this data from a push server which calls the below function to draw the unit's location on the map.
function drawUnit(unit)
{
//removeUnitMarkers();
var popupContent = "<h3>" + unit.number + "</h3>";
popupContent = popupContent + "<p><strong>Direction: </strong>" + unit.heading + "<br />";
popupContent = popupContent + "<strong>Speed: </strong>" + unit.velocity + "<br />";
popupContent = popupContent + "<strong>Last Update:</strong> " + unit.timestamp + "<br /></p>";
var markerLocation = new L.LatLng(unit.latitude,unit.longitude);
var marker = new L.Marker(markerLocation);
var unitNumber = unit.number;
var unitTest = 'test';
console.log(unitData);
unitLayerGroup.addLayer(marker);
marker.bindPopup(popupContent);
//unitMarkerCache.push(marker);
//map.panTo(markerLocation);
}
This works for a single unit but I need it to work for 2 or more units.
I'm struggling to think about what to do to draw the units on the map and be able to call a unique marker to destroy it and then redraw it. I've thought about defining an array or object to hold the data but I can't get it to work with a unit's number as part of the variable name.
var marker[unit.number] = {"unit":unit.number, "latitude":unit.latitude};
Doing something like the above var marker[unit.number] doesn't work; Firebug always throws an error:
missing ; before statement
http://10.10.1.10:86/map2.php
Line 161
This is line 161: var marker[unit.number] = new L.Marker(markerLocation);

I don't know how your eventlistener is setup, and how many unique units you have. but If you only have one unit = "90" and want to plot its location by listening to data sent from that unit, this code will work.
pointMarkers = [];
var listener = new EventSource("your event source");
listener.addEventListener('your call', function(e){
points = JSON.parse(e.data);
if(points.unit = '90') {
for (var i =0; i < pointMarkers.length; i++) {
mymap.removeLayer(pointMarkers[i]);
}
marker = L.marker([points.latitude, points.longitude]).addTo(mymap);
pointMarkers.push(marker);
}
}, false);

Related

How to define a button and a function inside js (React)

I am using MapBox to render a map. I have made a onClick function wherein when clicked on the map it shows the geocode information shown in the screenshot below through api.
Now what I want is to have a button below the table and when click on it I want it to execute a particular function, I have defined it but when clicked on it says Function is not defined
Code
map.current.on('click', function(e) {
var coordinates = e.lngLat;
var lng = coordinates.lng;
var lat = coordinates.lat;
console.log(lat);
console.log(lng);
var d = fetch("https://api.mapbox.com/geocoding/v5/mapbox.places/" + lng + "," + lat + ".json?access_token={token_value}").then(response => response.json()).then(function(data) {
console.log(data)
var str = "<table border='1'><tr><td><center>Title</center></td><td><center>Content</center></td></tr>"
for (let i in data["features"]) {
str = str + "<tr><td style='padding:5px'>" + data["features"][i]["place_type"][0] + "</td><td style='padding:5px'>" + data["features"][i]["place_name"] + "</td></tr>"
}
str = str + "</table>"
// button
str = str + "<button onClick={myFunction}>Save</button>"
function myFunction() {
console.log('Saved pressed');
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(str)
.addTo(map.current)
});
console.log(d);
});
Fix code as below
// button
str += `<button onclick="myFunction()"}>Save</button>`;
I would guess the button (and the function name defined for it) are created with a different scope than where you have defined your function. One of these might work:
Define your function as const myFunction = () => console.log("saved pressed").
Try referencing your function as this.myFunction

How to get values data from child

How to get last 20 records from firebase? I got:
dataset: undefined undefined
My firebase looks like this:
my code
var rootRefData = db.ref().child("users_db/user1/dataset");
rootRefData.once("value", snap => {
var key = snap.key;
var timestamp = snap.val().timestamp;
var log = snap.val().log;
var custom = "";
// create line chart
custom += key + ": " + timestamp + " " + log + "<br />";
console.log(custom);
counter++;
$("#chartsl-container-all").append(custom);
});
Try this:
var rootRefData = db.ref().child("users_db/user1/dataset");
rootRefData.once("value", snap => {
snap.forEach(function (snapshot) {
var key = snapshot.key;
var timestamp = snapshot.val().timestamp;
var log = snapshot.val().log;
var custom = "";
rootRefData is at node dataset, since you want to get timestamp and log, then you need to iterate inside the randomid using forEach to be able to get those values and the random id.

Map Route Direction Zoom to Segment

Basically I am trying to zoom to certain route segment when getting direction on OneMap. Here is the JavaScript codes where I trying to plot a route and zoom to certain route segment:
function getDirections() {
var routeData = new Route;
var from = document.getElementById('txtFrom').value
var to = document.getElementById('txtTo').value
//Draw out the line from the cordinate to another cordinate
routeData.routeStops = from + ";" + to;
//What type of mode will it do
routeData.routeMode = "DRIVE";
//can draw out untill the following coordiante
routeData.barriers = '36908.388637,35897.420831';
{
if (document.getElementById('CbAvoid').checked) {
routeData.avoidERP = "1";
}
else
routeData.avoidERP = "0";
}
routeData.GetRoute(showRouteData)
}
function showRouteData(routeResults) {
if (routeResults.results == "No results") {
alert("No Route found, please try other location.")
return
}
$('#divComputedDirection').show();
directions = routeResults.results.directions[0];
directionFeatures = directions.features;
var routeSymbol = new esri.symbol.SimpleLineSymbol().setColor(new dojo.Color([0, 0, 255, 0.5])).setWidth(4);
var mergedGeometry = new esri.geometry.Polyline()
mergedGeometry.addPath(routeResults.results.routes.features[0].geometry.paths[0])
OneMap.map.graphics.add(new esri.Graphic(mergedGeometry, routeSymbol));
//Display the total time and distance of the route
var htmlStr = "";
htmlStr += "<img class='close-image' onclick='closeDirectionResultDIV();' alt='close' src='img/closeDirectionResult.png' />";
htmlStr += "<span style='font-weight:bold;'><br /> Total distance: " + Math.round(directions.summary.totalLength) + "km" + "<br /> Total time: " + Math.round(directions.summary.totalTime) + "mins <br/></span>";
document.getElementById("divComputedDirection").innerHTML = htmlStr;
//List the directions and create hyperlinks for each route segment
for (var i = 0; i < directions.features.length; i++) {
var feature = directions.features[i]
document.getElementById("divComputedDirection").innerHTML += '<br>' + parseInt(parseInt(i) + 1) + ". " + feature.attributes.text + " (" + formatDistance(feature.attributes.length, "miles") + ", " + formatTime(feature.attributes.time) + ") " + '';
}
}
//Zoom to the appropriate segment when the user clicks a hyperlink in the directions list
function zoomToSegment(index) {
var segment = directionFeatures[index];
map.setExtent(segment.geometry.getExtent(), true);
if (!segmentGraphic) {
segmentGraphic = map.graphics.add(new esri.Graphic(segment.geometry, segmentSymbol));
}
else {
segmentGraphic.setGeometry(segment.geometry);
}
}
It did plot the route and show all the directions. But when I click on certain direction and zoom to segement, it throws me an error message which is Uncaught TypeError: Cannot call method 'getExtent' of undefined.
I wonder why is it so. Thanks in advance.
The root cause of your error is that you're trying to get the extent of a .geometry property that doesn't exist - that part is relatively easy. The problem, I think, is that you're looking for the geometry of each segment of the journey, and the return from OneMap's RouteTask doesn't give you that directly.
The geometry from the entire route is in
routeResults.results.routes.features[0].geometry.paths[0]
and the individual segments are in one of ESRI's fun compressed formats in the value:
routeResults.results.directions[x].features[y].compressedGeometry
There's some documentation and C# code for this compressed format here:
http://resources.esri.com/help/9.3/arcgisengine/ArcObjects/esrinetworkanalyst/INACompactStreetDirection_CompressedGeometry.htm
It should be relatively easy to port that C# code to JS if you really need the geometry of individual segments.
OneMap have a full working example here which shows how to process the results from the RouteTask, but unfortunately they don't attempt to extract the compressedGeometry field.
Edit: More sample code from ESRI here, with examples in C#/Java/Python.

Google Maps API v3: Looping through and adding polylines to a map

I've gone through the forums trying to search for solutions, and I've adapted my code for several problems I've come across, but this one eludes me. I'm trying to plot multiple points on a map (which works) and then draw lines between the points. Each marker contains information, such as latitude and longitude, as well as it's neighbor (the point that I want to draw the line to). I also give it the color I want the line, as different 'routes' can be in different colors. The only I can see being a problem is that I draw a line, set it on the map, and run the loop again for the next marker.
My code places the markers, places the information window for each marker, but doesn't draw the lines between the markers. Can anyone see where I've screwed up, or even if this is possible to do it in the way I'm doing it?
The reason I'm keeping the drawMap function separate is in the event users want to filter out visible data, I need to re-draw the map dynamically. So, I'm keeping the marker list globally so I can reference it even after the function has finished.
My code:
http://www.nku.edu/~sweikatam1/nkuPhysicalMapTest.html
The spot in particular with the issue is the function drawMap, which gets passed an array of objects, markerList, containing the latitude, longitude, color (for the polyline), and other bits of data.
The line placement:
for(var j = 0; j < markerList.length; j++){
if(markerList[j].name == markerList[i].neighbor){
var targetDestination = new google.maps.LatLng(markerList[j].latitude,markerList[j].longitude);
//alert(markerList[i].latitude + " " + markerList[i].longitude + " \r" + markerList[j].latitude + " " + markerList[j].longitude);
}
}
//set the pathway for the two points
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
new google.maps.LatLng(targetDestination)
];
//alert("Color: " + markerList[i].routeColor);
//set the line and color
var flightPath = new google.maps.Polyline({
path:flightPlanCoordinates,
strokeColor:markerList[i].routeColor,
strokeOpacity:2,
strokeWeight:5
});
//apply lines
flightPath.setMap(map);
The function as a whole:
function drawMap(markerList){
//alert("Starting drawMap");
//create the map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: new google.maps.LatLng(39.032253, -84.465015),
mapTypeId: google.maps.MapTypeId.HYBRID
});
var marker;
for (var i = 0; i <markerList.length; i++){
/*alert("markerList # i: " + markerList[i].name);
alert("Marker Data: " + "Name: " + markerList[i].name + "\r "
+ "Latitude: " + markerList[i].latitude + "\r "
+ "Longitude: " + markerList[i].longitude + "\r "
+ "Content Type: " + markerList[i].contentType + "\r "
+ "Image: " + markerList[i].image
+ "Color: " + markerList[i].routeColor);*/
var contentData = '<b>'+markerList[i].name +'</b>: '
+ markerList[i].latitude + ' x '
+ markerList[i].longitude + '<br/><p>'
+ markerList[i].contentType
+'</p><img src="' + markerList[i].image + " height=150 width=100>";
//create the marker
marker = new google.maps.Marker({
position: new google.maps.LatLng(markerList[i].latitude,markerList[i].longitude),
draggable: false,
icon: markerList[i].icon,
map:map,
content: contentData,
title:markerList[i].name
});
//find the neighbor for the current marker and set the destination coordinates
for(var j = 0; j < markerList.length; j++){
if(markerList[j].name == markerList[i].neighbor){
var targetDestination = new google.maps.LatLng(markerList[j].latitude,markerList[j].longitude);
//alert(markerList[i].latitude + " " + markerList[i].longitude + " \r" + markerList[j].latitude + " " + markerList[j].longitude);
}
}
//set the pathway for the two points
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
new google.maps.LatLng(targetDestination)
];
//alert("Color: " + markerList[i].routeColor);
//set the line and color
var flightPath = new google.maps.Polyline({
path:flightPlanCoordinates,
strokeColor:markerList[i].routeColor,
strokeOpacity:2,
strokeWeight:5
});
//apply lines
flightPath.setMap(map);
//handle open information windows
google.maps.event.addListener(marker,'click', function(){
closeInfos();
var info = new google.maps.InfoWindow({content: this.content});
info.open(map,this);
infos[0]=info;
});
//alert("Marker " + markerList[i].name + " placed.");
}
//alert("drawMap complete. Drawing lines");
<!-- DRAWING LINES COMPLETE -->
}
If anything here seems odd, confusing, or needs clarification, please let me know. Criticisms and ways of doing things better are always welcome. Thanks guys!
In defining, flightPlanCoordinates, the second LatLng was being created out of another LatLng (targetDestination). So just remove the new google.maps.LatLng portion and use the targetDestination directly. With this change, I saw a blue zigzag and a red one being drawn on the map.
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
targetDestination
];

Javascript Google Maps Changing Icons

I have been playing with Google maps I had it working but when I tried to change the Icons to Blue I lost some of the information in my pop up windows.
The first windows that opens is all correct but the second click on windows opens but the only thing the is correct is the point information the Lat & Lng if I remove the couston Icon back to the default it all works. i found the information on a site and tried to copy it into my script. I am just learning javascript and I am not sure where I when wrong.
The datetime alt speed and course are all ok on the frist window but fail on the click on window, the icons are now blue, if I remove the customIcons[call] from the statement var marker = createMarker(point,customIcons[call]); and replace it with datetime is seems to work. I thank all for having a look if there is anything that you think may help please advise.
My Script.....
function load() {
if (GBrowserIsCompatible()) {
// Get map (Version 2)
var map = new GMap2(document.getElementById("map"));
map.setUIToDefault();
// Default user interface
var icon = new GIcon();
icon.image = 'http://labs.google.com/ridefinder/images/mm_20_blue.png';
icon.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
var customIcons = [];
customIcons["VE9SC-9"] = icon;
// Get course
GDownloadUrl("http://guardian.no-ip.org/track/phpsqlajax_genxml_track_25.php",
function(data) {
var xml = GXml.parse(data);
var markers =
xml.documentElement.getElementsByTagName("marker");
var points = new Array(0);
// For polyline
// Loop through the markers
for (var i = 0; i < markers.length; i++) {
var datetime = markers[i].getAttribute("datetime");
var speed = markers[i].getAttribute("speed");
var course = markers[i].getAttribute("course");
var alt = markers[i].getAttribute("alt");
var call = markers[i].getAttribute("call");
var point =
new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
points[i] =
new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(point, customIcons[call]);
map.addOverlay(marker);
}
// End loop
// Polyline
var polyline = new GPolyline(points, "#0066cc", 2);
map.addOverlay(polyline);
// Set map centre (to last point), zoom level
map.setCenter(point, 13);
// InfoWindow HTML (last marker)
var html = "";
html += "<div id=\"infobox\">";
html += "VE9SC-9";
html += "<br />This is my last position on";
html += "<br />" + datetime;
html += " UTC";
html += "<br />" + point;
html += "<br />Aluitude ";
html += +alt;
html += " Feet ";
html += "<br />" + speed;
html += " MPH Last Recorded Speed";
html += "<br />" + course;
html += " deg Last Recorded Course";
html += "<br />ve9sc#rogers.com";
html += "<br />ve9sc.no-ip.org</div>";
html += "<br />Updated Via MySql PHP.";
html += "</div>";
map.openInfoWindowHtml(point, html);
});
}
}
// General markers
function createMarker(point, datetime) {
var marker = new GMarker(point, datetime);
var html = "";
html += "<div id=\"infobox\">";
html += "VE9SC-9";
html += "<br />This is my position on";
html += "<br />" + datetime;
html += " UTC";
html += "<br />" + point;
html += "<br />Aluitude ";
html += +alt;
html += " Feet ";
html += "<br />" + speed;
html += " MPH Last Recorded Speed";
html += "<br />" + course;
html += " deg Last Recorded Course";
html += "<br />ve9sc#rogers.com";
html += "<br />ve9sc.no-ip.org</div>";
html += "<br />Updated Via MySql PHP.";
html += "</div>";
GEvent.addListener(marker, 'click',
function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
It looks like you are using V2 of Google Map API (which kind of old). In this version the 2nd argument that you try to pass to GMarker should be an GMarkerOptions not an GIcon (assume API Version 2.5+)
From your code I think you are trying to pass GIcon object from customIcons[] in which is incorrect. I think you should inspect the datetime object here to make sure it's an GmarkerOptions not GIcon
var marker = new GMarker(point, datetime);
http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GMarker

Categories