I'm building a website that has, among the others, a photo gallery feature. In the gallery page, there's a map (google) with several markers and every marker is related to a specific photo.
I've got a 'markers' table in my database:
markers:
id | name | address | lat | lng | gallery_id
_______________________________________________________
1 | .. | .... |.. | .. | 2
2 | .. | .... |.. | .. | 2
3 | .. | .... |.. | .. | 3
4 | .. | .... |.. | .. | 3
5 | .. | .... |.. | .. | 10
......................
All the fields are populated with geolocated data and every row represents a specific photo uploaded by the user, all but gallery_id, that holds the id of the gallery that owns the photo.
In the gallery page there's the javascript to build up the google map:
<script type="text/javascript">
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
disableDefaultUI: true,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infoWindow = new google.maps.InfoWindow;
var bounds = new google.maps.LatLngBounds();
//phpsqlajax-xmlgenerator.php, get the data from database
downloadUrl("phpsqlajax-xmlgenerator.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("name");
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("lng")));
var html = "<b>" + name + "</b> <br/>" + address;
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
animation: google.maps.Animation.BOUNCE
});
bindInfoWindow(marker, map, infoWindow, html);
bounds.extend(marker.position);
}
map.fitBounds(bounds);
});
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
</script>
I provide to downloadURL the phpsqlajax-xmlgenerator.php file, with which I build the xml file holding the markers table data:
<?php
//Start xml file, create parent node
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers");
$parnode = $dom->appendChild($node);
// Opens a connection to a MySQL server
$conn = mysqli_connect('localhost', 'root', 'password', 'database');
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
//Select rows in the markers table
$query = "
SELECT * FROM `markers` WHERE 1;
";
$result = mysqli_query($conn, $query);
header("Content-type: text/xml");
// Iterate through the rows
while ($row = mysqli_fetch_assoc($result)){
// ADD TO XML DOCUMENT NODE
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("name",$row['name']);
$newnode->setAttribute("address", $row['address']);
$newnode->setAttribute("lat", $row['lat']);
$newnode->setAttribute("lng", $row['lng']);
$newnode->setAttribute("type", $row['type']);
}
echo $dom->saveXML();
?>
Everything works just fine so far and, as long there's only one gallery in the database, the map and the markers are correct.
Now comes my problem: I need a way to provide to phpsqlajax-xmlgenerator.php the gallery_id, in order to perform the right query since the old one just returns every rows of markers, no matter the gallery. I was thinking to put phpsqlajax-xmlgenerator.php code right on the top of the gallery.php page and generate the xml file directly on the page, but then what should I provide to the downloadURL function? gallery.php?. Another way I was thinking about is to put some sort of $_GET request in the downloadURL parameter, but I can't find a way to perform that properly.
Pass the gallery_id with the URL,e.g.:
downloadUrl("phpsqlajax-xmlgenerator.php?id=3", function(data) {
And build the sql based on the get-parameter:
$id=#intval($_GET['id']);
if($id<1){
exit();
}
$query = 'SELECT * FROM `markers` WHERE gallery_id='.$id;
Related
I pass php $var into Javascript from controller. $var has fetched addresses from DB. And i put it in Javascript. Now i can see the addresses in the console. No problem with that, I don't know why syntax error pop up too.
This is how I insert it into JS.
function initMap(){
var options = {
zoom:8,
center:
'{!! $estates[0]->address !!}'
}
var map = new google.maps.Map(document.getElementById("map"), options);
var marker = new google.maps.Marker({
position:
#foreach($estates as $addr)
'{!! $addr->address !!}',
#endforeach
map:map
});
var infoWindow = new google.maps.InfoWindow({
content:'content here'
});
marker.addListener('click', function () {
infoWindow.open(map, marker);
});
}
my foreach running without a problem I can see the addreses in the console but also at this line: '{!! $estates[0]->address !!}' error pops up too. Actually I am seeing the address not this line.
error is this:
Uncaught SyntaxError: Invalid or unexpected token
Do you have any idea? am I making syntax mistake. But if do that then how can I retrieving the addresses at the console?
Also having this error too at the same line:
Undefined variable: estates (View:
/var/www/html/laravel/resources/views/layouts/app.blade.php) (View:
/var/www/html/laravel/resources/views/layouts/app.blade.php)
Controller
public function index()
{
$estates = DB::table("allestates")
->get();
return view("home", compact('estates'));
}
the topic is different the duplicated ones. it's not pure JS i am working with Laravel.
I think one of the addresses contains the ' character. To avoid it use the addslashes function. You could do that in the controller:
public function index()
{
$estates = DB::table("allestates")->get()->map(function($estate) {
$estate->address = addslashes($estate->address);
return $estate;
});
return view("home", compact('estates'));
}
And the according js would be:
var options = {
zoom:8,
center: new google.maps.LatLng({{$estates[0]->lat}}, {{$estates[0]->long}});
}
Because you have multiple addresses, it means you will have multiple markers too. That being said your code should look something like:
function initMap(){
var options = {
zoom:8,
center: new google.maps.LatLng({{$estates[0]->lat}}, {{$estates[0]->long}});
}
var map = new google.maps.Map(document.getElementById("map"), options);
var infoWindow = new google.maps.InfoWindow({
content:'content here'
});
var markers = [];
#foreach ($estates as $key => $estate)
markers[{{$key}}] = new google.maps.Marker({
position: new google.maps.LatLng({{$estate->lat}}, {{$estate->long}});
map: map
});
markers[{{$key}}].addListener('click', function () {
infoWindow.open(map, markers[{{$key}}]);
});
#endforeach
}
You can use php variables inside laravel blade files as
var options = {
zoom:8,
center:
'{{$estates[0]->address}}'
}
I'm using this code to map power transformers on a leaflet map, but unfortunately when the map loads I don't find my data displayed. Can you please help me identify some problems(if any) in my code. I must admit that I'm new to web mapping so I just need some help here.
Here is the javascript code I'm using:
//global variables
var map,
fields = ["tx_id", "owner", "kva_rating", "prim_voltage", "sec_voltage", "serial_no", "area_name"],
autocomplete = [];
$(document).ready(initialize);
function initialize(){
$("#map").height($(window).height());
map = L.map("map", {
center: L.latLng(-0.7166700, 36.4359100),
zoom: 10
});
var tileLayer = L.tileLayer('https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoicmFqYWJueWFtYnUiLCJhIjoiY2lqbTB4cnpiMDA4bnZhbHh3Znl2aDAwZiJ9.YC_iahav7t9GPl-7XgB-yQ', {
attribution: 'Network Design © Rajab Inc., Map data © OpenStreetMap contributors, | Map Tiles: CC-BY-SA, Imagery © Mapbox',
maxZoom: 19,
minZoom: 1,
id: 'rajabnyambu.oo91e3ga',
accessToken: 'pk.eyJ1IjoicmFqYWJueWFtYnUiLCJhIjoiY2lqbTB4cnpiMDA4bnZhbHh3Znl2aDAwZiJ9.YC_iahav7t9GPl-7XgB-yQ'
}).addTo(map);
//next: add features to map
getData();
};
function getData(){
$.ajax("getData.php", {
data: {
table: "transformer",
fields: fields
},
success: function(data){
mapData(data);
}
})
};
function mapData(data){
//remove existing map layers
map.eachLayer(function(layer){
//if not the tile layer
if (typeof layer._url === "undefined"){
map.removeLayer(layer);
}
});
//create geojson container object
var geojson = {
"type": "FeatureCollection",
"features": []
};
//split data into features
var dataArray = data.split(", ;");
dataArray.pop();
//console.log(dataArray);
//build geojson features
dataArray.forEach(function(d){
d = d.split(", "); //split the data up into individual attribute values and the geometry
//feature object container
var feature = {
"type": "Feature",
"properties": {}, //properties object container
"geometry": JSON.parse(d[fields.length]) //parse geometry
};
for (var i=0; i<fields.length; i++){
feature.properties[fields[i]] = d[i];
};
//add feature names to autocomplete list
if ($.inArray(feature.properties.featname, autocomplete) == -1){
autocomplete.push(feature.properties.featname);
};
geojson.features.push(feature);
});
//console.log(geojson);
//activate autocomplete on featname input
$("input[name=area_name]").autocomplete({
source: autocomplete
});
var mapDataLayer = L.geoJson(geojson, {
pointToLayer: function (feature, latlng) {
var markerStyle = {
fillColor: "#CC5600",
color: "#CAF",
fillOpacity: 0.5,
opacity: 0.8,
weight: 1,
radius: 8
};
return L.circleMarker(latlng, markerStyle);
},
onEachFeature: function (feature, layer) {
var html = "";
for (prop in feature.properties){
html += prop+": "+feature.properties[prop]+"<br>";
};
layer.bindPopup(html);
}
}).addTo(map);
};
my getData.php file works well so I guess the problem lies within the javascript file. Here is the getData.php:
require ('networkdbinfo.php');
$dbc = pg_connect( "$host $port $dbname $credentials" );
if(!$dbc) {
echo "Not connected : " . pg_error();
exit;
}
// Get the table and fields data
$table= 'transformer';
$fields = ["tx_id", "owner", "kva_rating", "prim_voltage", "sec_voltage", "serial_no", "area_name"];
// Turn fields array into formatted string
$fieldstr="";
foreach ($fields as $i=> $field) {
$fieldstr=$fieldstr . "l.$field,";
}
// Get the geometry as geojson in EPSG:900913
$fieldstr=$fieldstr . "ST_AsGeoJSON(ST_Transform(l.geom, 900913))";
// Create basic SQL statement
$sql="SELECT $fieldstr FROM $table l";
//if a query, add those to the sql statement
if (isset($_GET['area_name'])){
$area_name = $_GET['area_name'];
$distance = $_GET['distance'] * 1000; //change km to meters
//join for spatial query - table geom is in EPSG:900913
$sql = $sql . " LEFT JOIN $table r ON ST_DWithin(l.geom, r.geom, $distance) WHERE r.area_name = '$area_name';";
}
// echo $sql;
// Send the query
if (!$response=pg_query($dbc, $sql)) {
echo "A query error occurred.\n";
exit;
}
// Echo the data back to the DOM
while ($row=pg_fetch_row($response)) {
foreach ($row as $i=> $attr) {
echo $attr.", ";
}
echo ";";
}
?>
You probably have the same issue as there:
Json file dosen't show up in google chrome
I.e. opening your page from File System in Chrome browser.
The solutions proposed in that post are to set up a local server or to open Chrome with specific parameters.
But you should be able to test it directly with Firefox instead.
I'm working with Googlemaps now. I use lattitude and longitude stored in the database. To call the data, I use simple ajax and it shows the latt and long as I wish.
However, It takes a long time to show the map based on the latt and long. Otherwise, It does not show anything. I don't know. How can I handle this?
Updated:
It looks there's a problem with the event.key onkeypress. I tried
clean code for that and it doesn't show anything !. ex: jsfiddle But That keyboard works on other code.
Here's the complete code:
JS/Ajax call the database through file inc.php:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script>
function strQuery(str) {
if (str.length == 0) {
document.getElementById("valdata").value = "-33.8474, 151.2631";
return;
}
else{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("valdata").value = xmlhttp.responseText;
script_dkill()
}
}
xmlhttp.open("POST", "inc.php?q="+str, true);
xmlhttp.send(null);
}
}
//start: calling maps
var map;
var strlng;
function script_dkill() {
strlng = document.querySelector("#valdata").value;
if (strlng) {
var latlng = new google.maps.LatLng(strlng);
var myOptions = {
zoom: 12,
center: latlng,
panControl: true,
zoomControl: true,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
addMarker(new google.maps.LatLng(strlng), map);
}
}
function addMarker(latLng, map) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: true,
animation: google.maps.Animation.DROP
});
return marker;
}
</script>
Here's the target(Output) in HTML:
<input id="qfront" name="qfront" placeholder="Ketik Nama Kampus ..." value="" type="text" onKeyPress="strQuery(this.value)"/>
<input id="valdata" name="valdata" type="text"/>
<div id="map_canvas" style="width:99.8%; height:280px; margin:0px; padding:0px;"></div>
and, here's the PDO the way I grab the data of latt and long (inc.php):
<?php
include('deep/cf/dbbs.php');
error_reporting(E_ALL);
?>
<?php
if(isset($_GET['q'])) {
$q = $_GET['q'];
}
$q = isset($_GET['q']) ? $_GET['q'] : '';
$nsUser="SELECT * FROM cliententry WHERE kampusterdekat=:q";
$uQuery = $mydb->prepare ($nsUser);
$uQuery->execute(array(':q' => $q));
$result = $uQuery->fetch(PDO::FETCH_ASSOC);
if ($result>0){
$googlemap=$result['googlemap'];
echo $googlemap;
}
else{
echo "<script>alert('Rent-house not registered yet');</script>";
}
?>
It's impossible to give you how the code running here. if you don't mind, please check here:
TEST-REAL-PAGE
Use keyword: "Universitas Lampung" since it's already inside the db.
I tends to focus on how the events work which I found it was wrong.
Data from db is interpreted as one value, ex: -2.9549663, 104.6929232
I must convert it into array first before called by JS in googlemap.
So, what makes it gray? It is because it didn't find the correct data format (like: -2.9549663, 104.6929232) in array. That's stupid of me.
Here's the way I convert which makes me stupid in a week:
var strlng = document.querySelector("#valdata").value;
var test1 = strlng.split(',');
var x = test1 [0];
var y = test1 [1];
After that, insert the x and y into the value of latt and long (latt and long is in array value), as follow:
var map;
function script_dkill() {
var strlng = document.querySelector("#valdata").value;
var test1 = strlng.split(',');
var x = test1 [0];
var y = test1 [1];
var latlng = new google.maps.LatLng(x,y);
var myOptions = {
zoom: 12,
center: latlng,
panControl: true,
zoomControl: true,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
addMarker(new google.maps.LatLng(x,y), map);
}
}
function addMarker(latLng, map) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: true,
animation: google.maps.Animation.DROP
});
return marker;
everything finally goes so amazing! Done.
now I learn one more from JS.
I make google map api v3. I want to make saving user-added form data by clicking on the marker, it appears info window, info window contains form data, then data added will be saved in json txt file.
Here is map.html code
<!DOCTYPE html >
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var marker;
var infowindow;
function initialize() {
var latlng = new google.maps.LatLng(-6.9667, 110.41677);
var options = {
zoom: 13,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), options);
var html = "<table>" +
"<tr> <td> Title:</td> <td><input type='text' name='title' id='title'/> </td> </tr> " +
"<tr> <td> Description:</td> <td><input type='text' name='description' id='description'/> </td> </tr> " +
"<tr> <td> Category:</td> <td><input type='text' name='category' id='category'/> </td> </tr> " +
"<tr> <td></td> <td> <input type='submit' id='submit' value='Submit' onclick='saveData()' /> </td> </tr> ";
infowindow = new google.maps.InfoWindow({
content: html
});
google.maps.event.addListener(map, "click", function(event) {
marker = new google.maps.Marker({
position: event.latLng,
map: map
});
google.maps.event.addListener(marker, "click", function() {
infowindow.open(map, marker);
});
});
}
function saveData() {
var title = escape(document.getElementById("title").value);
var description = escape(document.getElementById("description").value);
var category = escape(document.getElementById("category").value);
var latlng = marker.getPosition();
var url = "save_json.php?title=" + title + "&description=" + description +
"&category=" + category + "&lat=" + latlng.lat() + "&lng=" + latlng.lng();
downloadUrl(url, function(data, responseCode) {
if (responseCode == 200 && data.length <= 1) {
infowindow.close();
document.getElementById("message").innerHTML = "Location added.";
}
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map-canvas" style="width: 800px; height: 500px"></div>
<div id="message"></div>
</body>
</html>
Here is save_json.php
<?php
// Append new form data in json string saved in text file
// path and name of the file
$filetxt = 'dirdata/data.txt';
// check if all form data are submited, else output error message
if(isset($_POST['title']) && isset($_POST['lat']) && isset($_POST['lng']) && isset($_POST['description']) && isset($_POST['category'])) {
// if form fields are empty, outputs message, else, gets their data
if(empty($_POST['title']) || empty($_POST['lat']) || empty($_POST['lng']) || empty($_POST['description']) || empty($_POST['category'])) {
echo 'All fields are required';
}
else {
// gets and adds form data into an array
$data = array(
'title'=> $_POST['title'],
'lat'=> (float) $_POST['lat'],
'lng'=> (float) $_POST['lng'],
'description'=> $_POST['description'],
'category'=> $_POST['category'],
);
// path and name of the file
$filetxt = 'dirdata/data.txt';
$arr_data = array(); // to store all form data
// check if the file exists
if(file_exists($filetxt)) {
// gets json-data from file
$jsondata = file_get_contents($filetxt);
// converts json string into array
$arr_data = json_decode($jsondata, true);
}
// appends the array with new form data
$arr_data[] = $data;
// encodes the array into a string in JSON format (JSON_PRETTY_PRINT - uses whitespace in json-string, for human readable)
$jsondata = json_encode($arr_data, JSON_PRETTY_PRINT);
// saves the json string in "data.txt" (in "dirdata" folder)
// outputs error message if data cannot be saved
if(file_put_contents('dirdata/data.txt', $jsondata)) echo 'Data successfully saved';
else echo 'Tidak dapat menyimpan data di "dirdata/data.txt"';
}
}
else echo 'Form fields not submited';
?>
The data should be saved in data.txt like this, but it it doesn't work
[
{
"title": "title",
"lat": -6.9000,
"lng": -110.000,
"description": "description",
"category": "category"
}
]
Anyone can help me how to make it correct? Thank you very much for any help
I am trying to add markers to my Google map dynamically using a combination of ajax and php.
The first part of the code sends the latlng to the php file. The php file then returns the marker location needed.
When I alert the return part (ALERT TEST TO ENSURE PHP PROCESSED DATA CORRECTLY), it looks OK, but I cant seem to add the markers from the return on to my map.
See code below.
//SEND DATA TO URL (send to php file)
//RETURN DATA FOR PLACE MARKERS (this is what the return php file produces)
Many thanks,
//SEND DATA TO URL
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
HandleResponse(xmlHttp.responseText);
}}
xmlHttp.open("POST",'MYPHPFILE',true);
xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHttp.send("LATLON="+strLAT);
//RETURN DATA FOR PLACE MARKERS
var wxlatlng = new google.maps.LatLng(52,1);
var marker = new google.maps.Marker({
position: wxlatlng,
map: map,
icon: '../../icons/flags/traffic_light_red.png',
title: 'TEST', });
//RETURN DATA FOR PLACE MARKERS
var wxlatlng = new google.maps.LatLng(52,1.1);
var marker = new google.maps.Marker({
position: wxlatlng,
map: map,
icon: '../../icons/flags/traffic_light_red.png',
title: 'TEST', });
//ALERT TEST TO ENSURE PHP PROCESSED DATA CORRECTLY
function HandleResponse(response) {
document.getElementById('ResponseDiv').innerHTML = response;
alert($('#ResponseDiv').text());
}
The answer i found for my question was to use the php file to create the markers xml file and load the xml file via jQuery response
See code below;
jQuery.get(YOURXMLFILE, function(data) {
jQuery(data).find("marker").each(function() {
var eachMarker = jQuery(this);
var markerCoords = new google.maps.LatLng(
parseFloat(eachMarker.find("Lat").text()),
parseFloat(eachMarker.find("Lng").text())
);
var header = eachMarker.find("title").text();
var content = eachMarker.find("Content").text();
var wxicon = eachMarker.find("icon").text();
//--------------------------------------------------------------------------
marker = new google.maps.Marker({
position: markerCoords,
icon: wxicon,
map: map,
animation: google.maps.Animation.DROP,
title: header,
});
});
});