Uniquely identifying Leaflet Markers - javascript

I've done some research on this topic before, but I have yet to find an answer to my particular question. I am currently working with Leaflet.js. Each marker has popup text that is pulled from a MySQL database. However, some of this data does not display in the popup and is only associated with the marker.
What I would like to do is whenever a particular marker is clicked, data that is associated with it is echoed in a location other than in the popup (ie. in a DIV).
Is there a way to uniquely identify a marker so that you can pull data that is associated with it and echo it elsewhere?
Edit:
Here's some code to make things a bit clearer:
Here is some of my JS:
var json_data = <?php echo json_encode($data); ?>;
for (var i = 0; i < json_data.length; i++) {
L.marker([json_data[i].latitude, json_data[i].longitude])
.bindPopup(json_data[i].firstName + ' ' + json_data[i].lastName + '<br>' + '<strong>Date:</strong>' + ' ' + json_data[i].dateOccurred)
.addTo(map);
}
And here is my PHP:
$query = "SELECT * FROM incident, victim WHERE incident.incidentID = victim.incidentID";
//converting the data from mySQL to PHP
$data = array(); //setting up an emtpy PHP array for the data to go into
if($result = mysqli_query($db,$query)) {
while ($row = mysqli_fetch_assoc($result))
{
$data[] = $row;
}
}
?>
Basically I pull the data via PHP and then encode it into JSON.
Also, thank you for your help, guys!! :)

You can try adding a custom attribute to the marker and then get that attribute in the onClick event:
//Handle marker click
var onMarkerClick = function(e){
alert("You clicked on marker with customId: " +this.options.myCustomId);
}
//Create marker with custom attribute
var marker = L.marker([36.83711,-2.464459], {myCustomId: "abc123"});
marker.on('click', onMarkerClick);
Example on JSFiddle

Related

How can I access this variable in Google Maps API?

I have a google maps web application for a game where the user will click a google map marker, make a selection in the window that pops up and click submit. It uses AJAX to update the database with information selected by the user. The database is pre-populated with names of the markers and GPS coordinates, which are loaded. The markers are also placed accordingly upon load via XML.
I'm having trouble updating one row in my DB called quest with the user selected information when it's submitted. Currently, a user can select a marker and submit a quest, but it won't update the DB at all. I'm unsure on the correct WHERE statement to use. Here's my current SQL statement, I'm attempting to update a row called quest.
mysqli_query($con, "UPDATE markers SET quest= '$questName' WHERE markerName = '$markerName'");
This is what happens when the submit button is pressed.
if (document.getElementById("questType").value ==
"quest1") { //if quest1 is selected upon submission
alert("quest1");
var markerName;
var questName = "Quest 1";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "ajax.php?questName=" + questName + "&markerName=" + markerName, true);
xmlhttp.send(); //Sending the request to the server
ajax.php
<?php
include("connect.php");
require("call2.php");
$markerName = mysqli_real_escape_string($con, $_GET['markerName']);
$questName = mysqli_real_escape_string($con, $_GET['questName']);
$stmt = $con->prepare("UPDATE markers SET quest = $questName WHERE markerName = $markerName");
$stmt->bind_param($questName, $markerName);
$stmt->execute();
$stmt->close();
?>
Here is my relevant call file as well.
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers");
$parnode = $dom->appendChild($node);
include('connect.php');
$query = "SELECT * FROM markers WHERE 1"; // Select all the rows in the markers table
$result = mysqli_query($con, $query);
if (!$result) {
die('Invalid query: ' . mysqli_error($con));
}
// Iterate through the rows, adding XML nodes for each
while ($row = mysqli_fetch_assoc($result)) {
global $dom, $node, $parnode;
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("markerName",
$row['markerName']);
$newnode->setAttribute("quest", $row['quest']);
$newnode->setAttribute("lat", $row['lat']);
$newnode->setAttribute("longg", $row['longg']);
}
header("Content-type: text/xml");
echo $dom->saveXML();
Sorry if this is a lot, I think the problem is i'm not assigning a value to markerName. I don't get any errors, however when I hover over the ajaxphp in the network tab on chrome it looks like it's getting the questName but markerName remains undefined.
Here's where it's loading things in:
downloadUrl("call2.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("markerName"); //<------ here's where it's getting markerName
// var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("longg")));
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
I think I need to figure out a way to access name, but I'm unsure how to when it's local to the function which downloads the XML file.
connect.php
<?php
$con = mysqli_connect("localhost", "root", "", "pokestop-map");
?>
First of all, I think in some cases your Database Connection Credentials could be leaked if your Database is down and somebody is requesting ajax.php. If you want to use code in an production environment you should never leak errors to the client. Also I'm not sure if you're trying to add the Params to your Query through PHP's ability to evaluate variables in Strings, if so that is very unsecure and I would recommend you to read about Prepared Statements. Also I would recommend you to use PDO's (http://php.net/manual/de/book.pdo.php) instead of MySQLi but that's just a sidenote. I think the Problem here is that you don't bind your value to the Query. It's a long time ago that i've used MySQLi but I think you could do something like:
$stmt = $mysqli->prepare("UPDATE markers SET quest = ? WHERE markerName = ?");
$stmt->bind_param($questName, $markerName);
$stmt->execute();
$stmt->close();
Edit:
I would recommend you to look at ORM libraries which allow you to Map the Rows in a table to an object in PHP. There are a few of them out there like Doctrine or Idiorm. Working with Objects is much cleaner. But anyway I also wrote a little bit code which may help you, but I have to say its not tested.
DB.php (Holds an PDO in Singleton Pattern which will be used to communicate with the Database):
require_once('Config.php');
class DB {
private static $_instance = null;
private $_pdo;
private function __construct() {
try {
$this->_pdo = new PDO('mysql:host=' . Config::getDbHost() . ';dbname=' . Config::getDbName(), Config::getDbUser(), Config::getDbPass());
} catch(PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
/**
* #return PDO
*/
public function getPdo()
{
return $this->_pdo;
}
}
Config.php (Holds the settings needed to connect to the Database, you can extend the Class and parse some kind of configuration file to fill the values if you want):
class Config
{
private static $_dbHost;
private static $_dbName;
private static $_dbUser;
private static $_dbPass;
/**
* #return mixed
*/
public static function getDbHost()
{
return self::$_dbHost;
}
/**
* #return mixed
*/
public static function getDbName()
{
return self::$_dbName;
}
/**
* #return mixed
*/
public static function getDbUser()
{
return self::$_dbUser;
}
/**
* #return mixed
*/
public static function getDbPass()
{
return self::$_dbPass;
}
}
With these classes you should be able to do the following:
<?php
require_once('DB.php');
$pdo = DB::getInstance()->getPdo();
$stmt = $pdo->prepare('UPDATE markers SET quest = :questName WHERE markerName = :markerName');
$stmt->bindValue('questName', $_GET['questName']);
$stmt->bindValue('markerName', $_GET['markerName']);
$stmt->execute();
As I said this is not tested, but it should work. Maybe you have to fix includes and Parameter Binding...

Inserting markers and info windows (Google Maps) from a database using PHP and javascript

My objective is to obtain data from a table in a database and show it on the map. My table has three columns: LATITUD (stores the latitude)(type=float(10,6)), LONGITUD (stores the longitude)(type=float 10,6) and ASUNTO(stores the information)(type=VARCHAR). The first two have information of the location of the marker, while the third column stores information related to the marker. The content of this last column is the one I want to show with an info window.
To achieve this inside the body element of the page i have decided to insert a script element (javascript) which I use to create the map and to load all the information related to it.
Inside this javascript code I have included PHP code which is in charge of making a query to the database to obtain the content of the table we mentioned at the beggining in an associative array. Inside this code through a while loop I want to load all the markers with their corresponding info windows.
Loading the markers didn't gave me any problem, to load them I used this while loop code.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});';
}
Inside the PHP script I inserted this code and works fine to me. I have the problem when I want to add info windows for each marker which contain the information stored in the "ASUNTO" column mentioned at the beggining. When I modify the code shown above to add info windows I have problems. The code that is giving me problems is the one below.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var asunto = '. $row['ASUNTO'] . ';';
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});
var infowindow = new google.maps.InfoWindow({
content: asunto
});
infowindow.open(map, marker1);
';
}
I think that the code line that is giving me problems is the first one inside the loop, which I will show now below.
echo ' var asunto = '. $row['ASUNTO'] . ';';
The reason I believe this, is because the "infowindow" variable when I change its content to a string which is not obtained through PHP and is directly inserted doesn't gives me any problem and displays an info window when it is called using the "open"method. The next code below doesn't gives me any problem.
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
$row['LATITUD'].', '.$row['LONGITUD'].');
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
infowindow.open(map, marker1);
';
}
As you can see the content of the infowindow have changed and when I changed it, it worked correctly and the map was able to load. I would like to show info windows which display the information stored in the database rather than the string "hello" of the example above.
I would like to know why my approach is failing and how to resolve the problem in order to be able to show the info windows I want for each marker.
The problem is not with the database, nor the php. The problem is where you echo that data.
One simple example, it's quite obvious that this won't work
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
echo ' var myLatlng1 = new google.maps.LatLng('.
...
The while-loop creates multiple instances of this code. The variable myLatlng1 will simply be overwritten.
What you need to do, is separate the data from the functions.
So you generate 1 var.
It should be something like this (my php is a bit rusty, I hope I'm not generating errors):
<?php
$data = array(); // we make an empty object/array, we will fill it with the data in the rows
while ($row = $resultado->fetch( PDO::FETCH_ASSOC )) {
$data[] = array(
'LATITUD' => $row['LATITUD'],
'LONGITUD' => $row['LONGITUD'],
'ASUNTO' => $row['ASUNTO'],
);
}
// now we echo this variable, 1 variable containing all the data
$data_string = json_encode($data); // this turns php arrays into a javascript-readable object
echo 'var my_data = ' . $data_string .';'; // notice which ; is for javascript and which is for php
?>
var my_data will be something like this (I'll insert some locations in Brussels):
var my_data = [{"LATITUD":"50.89496405015655","LONGITUD":"4.341537103056892","ASUNTO":"Atomium"},{"LATITUD":"50.84501941894387","LONGITUD":"4.349947169423087","ASUNTO":"Manneken Pis"},{"LATITUD":"50.83847065124941","LONGITUD":"4.376028969883903","ASUNTO":"European Parliament"}];
Now the javascript. How do you use infowindows? I'll use my_data hard coded, so you can copy/paste this code and test the javascript.
don't forget your API key
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
<div id="map"></div>
<script>
var my_data = [{"LATITUD":"50.89496405015655","LONGITUD":"4.341537103056892","ASUNTO":"Atomium"},{"LATITUD":"50.84501941894387","LONGITUD":"4.349947169423087","ASUNTO":"Manneken Pis"},{"LATITUD":"50.83847065124941","LONGITUD":"4.376028969883903","ASUNTO":"European Parliament"}];
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.869754630095834, lng: 4.353812903165801},
zoom: 12
});
for(var i=0; i<my_data.length; i++) {
// marker
var position = {lat: Number(my_data[i].LATITUD), lng: Number(my_data[i].LONGITUD)};
var marker = new google.maps.Marker({
position: position,
title: my_data[i].ASUNTO,
map: map
});
// infowindow
var infowindow = new google.maps.InfoWindow({
content: my_data[i].ASUNTO,
map: map,
position: position
});
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>

Issue with PHP and Javascript when building auto suggest text box

I'm trying to build a simple auto suggest input bar that connects to a MySql database and retrieves data. The issue that I'm running into is that when I type in the name of an object that I know exists in the databse, the text bar doesn't return any results, instead it just provides me with an empty dropdown box.
The best I can tell, the issue has to do with the javascript that is used within the PHP portion of the code. Unfortunately, I can't seem to figure out why it's causing an issue.
<?php
mysql_connect("host", "user", "passsword") OR DIE ('Unable to connect to database! Please try again later.');
mysql_select_db('DBName');
$query = 'SELECT Device_type FROM Device';
$result = mysql_query($query);
$counter = 0;
echo"<script type='text/javascript'>";
echo"this.nameArray = new Array()";
if($result) {
while($row = mysql_fetch_array($result)) {
echo("this.nameArray" .$row ['Device_type'] . "';");
$counter += 1;
}
}
echo("</script>");
?>
When I take out the echo"<script type='text/javascript'>"; and echo"this.nameArray = new Array()"; then It displays the Device_type content on the top of the page when the page is loaded. This obviously isn't what I want, but it does prove that the database connection is at least set up correctly. Since this chunk of PHP is referring to some javascript, I will also prove the function in which it's referring to.
function doSuggestions(text) {
var input = text;
//window.alert(text);
var inputLength = input.toString().length;
var code = "";
var counter = 0;
while(counter < this.nameArray.length) {
var x = this.nameArray[counter]; // avoids retyping this code a bunch of times
if(x.substr(0, inputLength).toLowerCase() == input.toLowerCase()) {
code += "<div id='" + x + "'onmouseover='changeBG(this.id);' onMouseOut='changeBG(this.id);' onclick='doSelection(this.innerHTML)'>" + x + "</div>";
}
counter += 1;
}
if(code == "") {
outClick();
}
document.getElementById('divSuggestions').innerHTML = code;
document.getElementById('divSuggestions').style.overflow='auto';
}
Any suggestions as to why the suggestion box isn't providing suggestions when I start typing? If I type A into the text box, the suggestion box should appear showing me all items in the database that start with A.
there are some errors in your js strings
`echo"var nameArray = new Array()";`
`echo("nameArray.push('" .$row ['Device_type'] . "');");`
that way you'll push device types into the nameArray var.

Creating D3 Line Graph Based off of Drop-down selection

I am trying to create a D3 line graph that will display a graph specific to the item that is selected in the drop-down menu. I have one script that queries my MySQL database and fills a drop-down menu with all of the correct options. From there, I want to click on an option and go to another page that creates a line graph based off of that selection. When I click on an option, I use json_encode to create a JSON object that should be compatible with D3.
I have another script that deals completely with drawing the graph and try to use d3.json to get the JSON object that is created when the specific selection is clicked. Whenever I try to load the graph page, it is completely blank. I am not sure if what I am trying to do is even possible. I have not tried including the drop-down in the same script as the one that creates the graph but do not think that I will be able to get the information from the database the same way.
Any guidance or suggestions would be greatly appreciated. I can post the code later if it is determined what I am trying to do is possible. Thanks!
EDIT:
This is the script that queries my database for the users that are put in the drop-down menu and then queries the database again for that selection's data. The drop-down menu has the desired result and the data is correctly echoed as well.
<?php
if (isset($_POST['name']))
{
$out = $_POST['name'];
$temp = explode(",", $out);
$populate_selection = "SELECT id, lastname, firstname FROM users WHERE id != '$temp[0]' ORDER BY lastname";
$out = $temp[1] . ', ' . $temp[2];
$student_hours = "SELECT ai_averages.user_id, ai_averages.title, ai_averages.hours FROM ai_averages INNER JOIN users ON ai_averages.user_id = users.id WHERE $temp[0] = ai_averages.user_id";
}
else
{
$temp[0] = " ";
$populate_selection = "SELECT id, lastname, firstname FROM users ORDER BY lastname";
$student_hours = "SELECT ai_averages.user_id, ai_averages.title, ai_averages.hours FROM ai_averages INNER JOIN users ON ai_averages.user_id = users.id WHERE $temp[0] = ai_averages.user_id";
$out = " ";
}
$result = $mysqli->query($populate_selection);
$option = "<option value= '{$temp[0]}'>$out</option>";
while($row = mysqli_fetch_assoc($result)) {
$option .= "<option value = '{$row['id']}, {$row['lastname']}, {$row['firstname']}'>{$row['lastname']}, {$row['firstname']} </option>";
}
if($student_results = $mysqli->query($student_hours))
{
$data = array();
for ($x = 0; $x < mysqli_num_rows($student_results); $x++)
{
//this array contains the data that I want in my graph
//the correct data is echoed every time that I click on the different choices
$data[] = mysqli_fetch_assoc($student_results);
}
echo json_encode($data, JSON_PRETTY_PRINT);
}
?>
<form id = "hello" method = "POST" >
<select name = "name" onchange = 'this.form.submit()'> <?php echo $option; ?> </select>
</form>
I then try and use d3.json("filename.php", etc) to get the information from the $data array but this has not worked.

Google map custom marker based on database

In 2 weeks I explored much about Google maps. I am try read a forum and tutorial. But I got this problem when I am going to develop a GIS web. I am using Google maps apiv3, postgre database, and php. I have so much row in my database. Now I only can show multiple marker based on my database, but what I after is the marker have a unique icon based on column content in database like a type 1 = 1.png type 2 = 2.png. the problem is the type is too many, so it is impossible to definition them by manual (because so many type, I already have about 30 type of content in database column ) . I get database value using json. I've already try read forum and some tutorial, but I can't find the answer. sorry for my bad english. please help me, thanks.
this is the code index.php and json.php :
<html lang="en">
<head>
<script type="text/javascript">
function initialize(){
var peta;
var gambar_tanda;
gambar_tanda = 'assets/images/enseval.jpg';
var x = new Array();
var y = new Array();
var customer_name = new Array();
var rayon_name = new Array();
// posisi default peta saat diload
var lokasibaru = new google.maps.LatLng( -1.2653859,116.83119999999997);
var petaoption = {
zoom: 5,
center: lokasibaru,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
peta = new google.maps.Map(document.getElementById("map_canvas"),petaoption);
var infowindow = new google.maps.InfoWindow({
content: ''
});
// memanggil function ambilpeta() untuk menampilkan koordinat
url = "json.php";
$.ajax({
url: url,
dataType: 'json',
cache: false,
success: function(msg){
for(i=0;i<msg.enseval.customer.length;i++){
x[i] = msg.enseval.customer[i].x;
y[i] = msg.enseval.customer[i].y;
customer_name[i] = msg.enseval.customer[i].nama_customer;
//rayon_name[i] = msg.enseval.customer[i].nama_rayon
var point = new google.maps.LatLng(parseFloat(msg.enseval.customer[i].x),parseFloat(msg.enseval.customer[i].y));
tanda = new google.maps.Marker({
position: point,
map: peta,
icon: gambar_tanda,
clickable: true
});
bindInfoWindow(tanda, peta, infowindow, msg.enseval.customer[i].nama_customer );
}
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function bindInfoWindow(tanda, peta, infowindow, data) {
google.maps.event.addListener(tanda, 'click', function() {
infowindow.setContent(data);
infowindow.open(peta, tanda);
});
}
</script>
<?php
require ('config.php');
$rayon = $_POST['rayon'];
$cabang = $_POST['org_id'];
//echo "$rayon, $cabang, $rayonhasil";
$sql = "SELECT distinct org_id, customer_name, attribute16, attribute17 FROM hasilgis";
$data = pg_query($sql);
$json = '{"enseval": {';
$json .= '"customer":[ ';
while($x = pg_fetch_array($data)){
$json .= '{';
$json .= '"id_customer":"'.$x['org_id'].'",
"nama_customer":"'.htmlspecialchars($x['customer_name']).'",
"x":"'.$x['attribute17'].'",
"y":"'.$x['attribute16'].'"
},';
}
$json = substr($json,0,strlen($json)-1);
$json .= ']';
$json .= '}}';
echo $json;
?>
I'm not sure what's the problem :)
The only thing you must do is to generate icons for all types. You don't have to do it manually - just create a scipt that will generate icons of different colors for every type and name it like 1.jpg, 2.jpg, ...
Pass type via your json message and than on client side create icon url dynamically:
gambar_tanda = 'assets/images/'+msg.enseval.customer[i].type+'.jpg';

Categories

Resources