Why a layer was incorrectly reloaded? - php

I've got a problem that was discribed over there:
how to correctly reload fusion tables layer?
Briefly:
i have a fusion table that changes very often.
And i have a javascript code that allows to visualize location information from database:
Thanks everyone, i've managed to solve this thing. This is the code that works as it should:
var map;
var layer;
function initialize() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: new google.maps.LatLng(60,30),
zoom: 9,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layer = new google.maps.FusionTablesLayer({
query: {
select: 'location',
from: '3415835'
}
});
layer.setMap(map);
refreshMap();
}
function refreshMap(){
layer.setOptions({
query: {
select: 'location',
from: '3415835',
where: "location not equal to" + (-1 * Math.floor(Math.random() * 10000000)).toString()
}
});
setTimeout('refreshMap()',5000);
}
At first t thought that my code is wrong. But after testing i discovered that layer is
being reloaded incorrectly: when new point is added i can see it on one zoom level but on
another level it dissapears. i dnon't know what's causing this: browser is cashing map or
script is wrong or smth else. Can someone help me?

Related

MapBox addLayer/addSource not adding points from geoJson created from php

I'm trying to create a map with points from my geoJson data. Currently the map is not showing any of the points I would like it to look something like this https://docs.mapbox.com/mapbox-gl-js/example/data-driven-circle-colors/
but with just one color circle (so the properties is not important).
var geoJson = <?php echo json_encode($geojson, JSON_NUMERIC_CHECK); ?>;
map.on('load', function () {
// add source and layer for museums
map.addSource('points', {
type: 'geojson',
data: geoJson
});
map.addLayer({
'id': 'points',
'type': 'circle',
'source': 'points',
'layout': {
// make layer visible by default
'visibility': 'visible'
},
'paint': {
'circle-radius': 3,
'circle-color': 'rgba(55,148,179,1)'
},
})
});
I know my php works since I used it earlier with what's below and it works fine (creates a bunch of markers but it is too slow and I want circles rather than the default marker shape.)
var myLayer = L.mapbox.featureLayer().addTo(map);
myLayer.setGeoJSON(geoJson);
myLayer.on('click', function(e) {
window.open(e.layer.feature.properties.url);
});

Leaflet Search Control - Cannot read property 'call' of undefined

I am having an issue with Leaflet Control Search, I am testing on C9.io, using Laravel 5.2, I am trying to search a L.geojson layer but all it comes up with is "Location not Found"
and the console gives error:
"Cannot read property 'call' of undefined"
I have a global variables that holds the map, L.geojson layers, and tiles.
var map, allcalls, mapquest;
mapquest = new L.TileLayer("http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png", {
maxZoom: 18,
subdomains: ["otile1", "otile2", "otile3", "otile4"],
});
map = new L.Map('map', {
center: new L.LatLng(39.90973623453719, -93.69140625),
zoom: 3,
layers: [mapquest]
});
var promise = $.getJSON("leaflet_php/get_users.php");
promise.then(function(data) {
allcalls = L.geoJson(data, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.fn + '<br>' +feature.properties.gender + '<br>' + feature.properties.addr + '<br>'+ feature.properties.city );
}
});
map.fitBounds(allcalls.getBounds(), {
padding: [20, 20]
});
allcalls.addTo(map);
});
Then I start the L.control.search, and it shows on the map but when I search I get no results the loader gif never stops and I get console error "Cannot read property 'call' of undefined"
var controlSearch = new L.Control.Search({
layer: allcalls,
position:'topleft',
propertyName: 'city',
});
map.addControl( controlSearch );
I am generating the json using https://github.com/bmcbride/PHP-Database-GeoJSON. My Json has at least 1000 features, each feature has 30 properties. So this is an abbreviated version. This is a sample of the json I get:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry": {"type":"Point","coordinates":[-80.191626,26.339826]},"properties":{"id":1,"fn":"SAMUEL","mi":null,"ln":"STANTON","name_pre":"MR","addr":"9 HONEYSUCKLE DR","apt":null,"city":"AMELIA","st":"OH","zip":45102,"z4":9722,"dpc":99,"fips_cty":25,"latitude":26.339826,"longitude":-80.191626,}},
Any help is greatly appreciated. Thanks in advance.
You should instantiate L.Control.Search within your Promise callback, or at least use the setLayer() method within that callback.
It looks like you have a classic asynchronous issue: you initiate an AJAX request (through jQuery's getJSON), which will assign the value of your allcalls variable once resolved.
In parallel, you instantiate your L.Control.Search and specify allcalls as the Layer Group to be searched in. However, at that time, the AJAX is still processing (i.e. not resolved), so allcalls is still unassigned (i.e. undefined).
Therefore your Search Control knows nothing about the L.geoJson layer group that is built later on in the AJAX resolution.

Cakephp form input with autocomplete

I am using CakePhp 2.2.1 and I am having some problems to implement what I just asked in the title, I found several tutorials but most of them are for cakephp 1.3 and the others are not what I want to do. I have a "events" table which contains a "player_id" thus a Player has many Events and an Event belongs to a Player.
In my Event add form I proceed as the cookbook says and I get a dropdown list of players to choose from, however what I want is to just write the names of the players and select the one I want from the autocomplete results. Also these players must be from the team that I select before that. Any ideas?
Thanks in advance.
Special thanks to Andrew for pointing out this api.jqueryui.com/autocomplete. However there is not a real guide to use this one. So i found this post, which explains what Abhishek's second link says but I could understand it better. So here is my solution if anyone is interested:
1 - Download from the autocomplete page the .js you need. Save it in app/webroot/js
2 - Either in your app/View/Layouts/default.ctp or in the view you want to use the autocomplete add:
echo $this->Html->script('jquery-1.9.1.js');
echo $this->Html->script('jquery-ui-1.10.3.custom.js');
echo $this->fetch('script');
3 - In your view add (mine was add_goal.ctp):
<script>
$(document).ready(function(){
var myselect = document.getElementById("EventTeam"); //I needed to know which team I was looking players from.
var team = myselect.options[myselect.selectedIndex].value; //"EventTeam" was a dropdown list so I had to get the selected value this way.
$("#EventPlayer").autocomplete({
source: "/events/autoComplete/" + team,
minLength: 2, //This is the min ammount of chars before autocomplete kicks in
autoFocus: true
});
$("input:submit").button();
$("#EventPlayerId").autocomplete({
select: function(event, ui) {
selected_id = ui.item.id;
$('#EventAddGoalForm').append('<input id="EventPlayerId" type="hidden" name="data[Event][player_id]" value="' + selected_id + '" />');
}
});
$("#EventPlayerId").autocomplete({
open: function(event, ui) {
$('#EventPlayerId').remove();
}
});
});
</script>
4 - In your Controller (mina was EventController.php):
public function autoComplete($team = null){
Configure::write('debug', 0);
$this->autoRender=false;
$this->layout = 'ajax';
$query = $_GET['term'];
$players = $this->Event->Player->find('all', array(
'conditions' => array('Player.team_id' => $team, 'Player.name LIKE' => '%' . $query . '%'),
'fields' => array('name', 'id')));
$i=0;
foreach($players as $player){
$response[$i]['id']=$player['Player']['id'];
$response[$i]['label']=$player['Player']['name'];
$response[$i]['value']=$player['Player']['name'];
$i++;
}
echo json_encode($response);
}
visit below link ,this might help you as the ajax helper is no more in cake2.X versions core all related functionality moved to JS helper class.(here third one link for AJAX helper for contributed by user may help you)
http://bakery.cakephp.org/articles/matt_1/2011/08/07/yet_another_jquery_autocomplete_helper_2
or
http://nuts-and-bolts-of-cakephp.com/2013/08/27/cakephp-and-jquery-auto-complete-revisited/
or
http://bakery.cakephp.org/articles/jozek000/2011/11/23/ajax_helper_with_jquery_for_cakephp_2_x
You need to use ajax because your autocomplete-results depends on the team you have selected.
Something like this in jquery:
var team = $('#teamdropdown').find(":selected").text();
$.ajax({
type: "POST",
url: 'http://domain.com/playersdata',
data: {'team':team},
success: function(data){
console.log(data);
//put data in for example in li list for autocomplete or in an array for the autocomplete plugin
},
});
And in cake on playersdata page (Controller or model) something like this.
if( $this->request->is('ajax') ) {
$arr_players = $this->Players->find('all', array('conditions'=>array('team'=>$this->request->data('team')))); //pr($this->request->data) to get all the ajax response
echo json_encode($arr_players);
}
Also set headers to a json respons and $this->layout = null; to remove the layout tpl.
Another solution would be to use json_encode in your php and pass it to js-code like
<script>var players = <?php echo json_encode($array_players_with_teams); ?>; </script>
This solution is only interesting for a small amount of data, if you have a big database with teams and players I wouldn't recommend this, because why load all this data if you only need just a bit of it...
I didn't test the code but it should help you to go on...
Good luck!

Fire click event on a highchart column drilldown chart on clicking x axis for drill down reports

I want to drill down through column chart in highcharts. I have a 3 level drill down with each having at least 20 x-axis labels.Right now drill down is working for column click. I want to do the same thing on x axis click.
Based on my research i found this probable solution. What I want to achieve can be seen here on clicking x-axis labels.
The function i used to achieve this functionality
function(chart) {
//console.log(chart.xAxis[0].ticks[0]);
$.each(chart.xAxis[0].ticks, function(i, tick) {
tick.label.on('click', function() {
var drilldown = chart.series[0].data[i].drilldown;
if (drilldown) { // drill down
chart.setTitle({
text: drilldown.name
});
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color, drilldown.level , drilldown.ytitle);
} else { // restore
setChart(name, categories, data, null, level , 'Total Agent score');
chart.setTitle({text: "Agent Performance Drill Down Report"});
chart.setTitle(undefined, { text: 'Click the Columns to view Drill Down Reports.' });
}
});
});
}
The problem: It works with most of the x-labels but not all. This can be seen # this fiddle the label drill down does not work at all 3 levels on all labels.
Also, here is the post I made on highchart forum for reference
You are adding the handlers at chart load, some of the axis labels won't be present at that time, hence those labels won't respond to the click event
As a quick (read dirty) fix you can add the same handler that you have for the load to the redraw, so the new labels that are created will bind to it.
You can bind the same function to the redraw (this happens when the x-axis labels are changed too, you can replace with a less frequent event that suits the need too) event, so every time the chart is redrawn you unbind (since I am unsure of the lifetime of the labels in highchart, if an exisiting label is reused for the new drilled down chart, it would be safer to remove) any existing click handler as follows for each tick
$(tick.label.element).unbind('click');
and then add the click handler
var bindAxisClick = function() {
$.each(this.xAxis[0].ticks, function(i, tick) {
$(tick.label.element).unbind('click');
$(tick.label.element).click(function() {
var drilldown = chart.series[0].data[i].drilldown;
if (drilldown) { // drill down
chart.setTitle({
text: drilldown.name
});
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color, drilldown.level, drilldown.ytitle);
} else { // restore
setChart(name, categories, data, null, level, 'Total score');
chart.setTitle({
text: "Drill Down Report"
});
chart.setTitle(undefined, {
text: 'Click the Columns to view Drill Down Reports.'
});
}
});
});
};
Modify the chart options to add the redraw and load handlers
chart :{
...
events: {
redraw: bindAxisClick ,
load:bindAxisClick
},
...
}
Dril down from x-axis labels # jsFiddle

Resize info window of google map V3

I am facing huge problem to solve info window size. I want to show a image block and some text information in info window but after place the content info window size increased i have read some threads but no luck with my code. Can any one help me to sort it out.
// Creating an object literal containing the properties
// we want to pass to the map
var options = {
zoom: 5,
center: new google.maps.LatLng(44.913990, 15.205078),
mapTypeId: google.maps.MapTypeId.ROADMAP ,
};
// Creating the map
var map = new google.maps.Map(document.getElementById("map"), options);
// Creating a LatLngBounds object
var bounds = new google.maps.LatLngBounds();
// Creating an array that will contain the coordinates
// for New York, San Francisco, and Seattle
var content = [];
var places = [];content.push('Some html');
places.push(new google.maps.LatLng(44.913990, 15.205078));
// Creating a variable that will hold
// the InfoWindow object
var infowindow;
// Looping through the places array
for (var i = 0; i < places.length; i++)
{
// Adding the markers
var marker = new google.maps.Marker({
position: places[i],
map: map,
icon: "/themes/garland/images/beach_icon_gmap.png"
// title: "Place number " + i
});
// Wrapping the event listener inside an anonymous function
// that we immediately invoke and passes the variable i to.
(function(i, marker) {
// Creating the event listener. It now has access to the values of
// i and marker as they were during its creation
google.maps.event.addListener(marker, "click", function() {
// Check to see if we already have an InfoWindow
if (!infowindow) {
infowindow = new google.maps.InfoWindow({
maxWidth: 20,
maxheight: 20
});
}
// Setting the content of the InfoWindow
infowindow.setContent(content[i]);
// Tying the InfoWindow to the marker
infowindow.open(map, marker);
});
})(i, marker);
// Extending the bounds object with each LatLng
bounds.extend(places[i]);
}
// Adjusting the map to new bounding box
// map.fitBounds(bounds)
Any help would be greatly appreciated. Thanks in advance.
The first thing I notice in your code: maxWidth is a valid property of the InfoWindowOptionsapi-doc object that is passed to the InfoWindow constructor, but maxheight is not. You won't be able to treat the InfoWindow as a strict or rigid container, although maxWidth will constrain the width. An InfoWindow is always sized to contain whatever content it has been provided. From the API Doc:
The InfoWindow will be sized according to the content. To set an
explicit size for the content, set content to be a HTML element with
that size.
That said, you are able to control the size, display, color, etc. of an InfoWindow by defining a CSS class and applying the styling rules to the content of the window. Taking the CSS approach to the content will pretty much give you complete control over the size of the content, because the InfoWindow just functions as a container for the content. If a CSS rule results in content of the correct size, your InfoWindow will be the correct size.

Categories