I develop a website with Openlayers 3 and need to yours helps.
My web page is shared in two parts: the listing display and map display.
I have create the markers that is animated by the cluster.
var features = [];
$.ajax({
url: urlUpdate,
dataType: 'json',
async: false,
success: function(json1){
$.each(json1, function (key, data) {
if (key === 'features') {
$.each(data, function (k, v) {
if (v.type === 'Feature') {
if (v.geometry.coordinates.length > 1){
features[k] = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(v.geometry.coordinates, 'EPSG:4326', 'EPSG:3857')),
id: v.properties.id,
name: v.properties.name,
lieu: v.properties.lieu,
});
}
}
});
}
});
}
});
var source = new ol.source.Vector({
features: features
});
var clusterSource = new ol.source.Cluster({
distance: 40,
source: source
});
var clusters = new ol.layer.Vector({
source: clusterSource,
style: ajouterStyle
});
var oldMarkers = map.getLayers().a[2];
map.removeLayer(oldMarkers);
map.addLayer( clusters );
The listing display need to update the map displaying and vice versa.
map.getView().on('change:resolution', function(evt){
var myLayer = map.getLayers().getArray()[2];
myLayer.getSource().forEachFeature(function(feature){
var geom = feature.getGeometry();
var coord = geom.getCoordinates(); //this is valid for a ol.geom.Point
var nb = feature.get('features').length;
var content = '';
if( nb === 1 ){
var name = feature.get('features')[0].get("name");
var date = feature.get('features')[0].get("date");
var id = feature.get('features')[0].get("id");
var content = '<li class="events">\n\
<div class="content_events">\n\
'<a href="?event=' + id +'" >' + name + "</a>\n\
<p>" + date + "</p>\n\
</div>\n\
</li>";
} else{
for( i=0; i< nb; i++){
var name = feature.get('features')[i].get("name");
var date = feature.get('features')[i].get("date");
var id = feature.get('features')[i].get("id");
content += '<li class="events">' +
'<div class="content_events">\n\
'<a href="?event=' + id + '" >' + name + "</a>"+
"<p>" + date + "</p>\n\
</div>\n\
</li>";
}
$("#listing_events").html('<ul class="list-event">' + content + '</ul>')
});
With this method I get the information of all markers, I need to get the marker displayed on the screen.
Thanks for your helps.
I have resolve my problem by :
var source = new ol.source.Vector({ features: features }); var bb = source.getExtent(); map.getView().fitExtent( bb, map.getSize() );
Thanks
Related
I'm trying to iterate a nested API response and display them inside a html. I managed to do single image because the response only have single value.
**API response **
{"result":{"totalResults":5861511,"products":[{"productTitle":"S-XL Plus Size Tunic Autumn <font><b>Women</b></font> Dresses Casual Cartoon Print Christmas Dress Casual Loose Long Sleeve Party Dress Vestidos","originalPrice":"US $7.98","imageUrl":"https://ae01.alicdn.com/kf/H3ba2899c892d4a88a5f704453c39942ae/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg","productUrl":"https://www.aliexpress.com/item/S-XL-Plus-Size-Tunic-Autumn-Women-Dresses-Casual-Cartoon-Print-Christmas-Dress-Casual-Loose-Long/4000353066650.html","allImageUrls":"https://ae01.alicdn.com/kf/H3ba2899c892d4a88a5f704453c39942ae/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/H218b19ee8bfc4f6ebe74b4297ca8395f5/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/H14b48746d6eb4d5788a7a9f6ce37195c7/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/Hb4b1f8b6223d4e7c88208751bfa681886/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/Hcfd17f95ac85470d9550d13f3683adc1I/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg}]},"errorCode":20010000,"currentPageNum":0,"totalPageNum":0}
main.js
$(function (){
var $orders = $('#orders');
var $productimage = $('#productimage');
var $output = $('#output');
$.ajax({
type: 'GET',
url: 'http://gw.api.alibaba.com/openapi/param2/2/portals.open/api.listPromotionProduct/9420?fields=productUrl,allImageUrls,imageUrl,originalPrice,productTitle&keywords=women',
success: function(orders){
$.each(orders, function(i, order){
$orders.append('' + order.products[0].productTitle + '');
$output.append(order.products[0].allImageUrls[1]);
// $productimage.append('<img class="pic-1" src="' + order.products[0].imageUrl + '">'); // single image
});
}
});
});
Result generated
"t"
How do you create a loop for $output from allImageUrls ?
You need to split the allImageUrls and then run them in a loop as follows:
var result ={
"result": {
"totalResults": 5861511,
"products": [
{
"productTitle": "S-XL Plus Size Tunic Autumn <font><b>Women</b></font> Dresses Casual Cartoon Print Christmas Dress Casual Loose Long Sleeve Party Dress Vestidos",
"originalPrice": "US $7.98",
"imageUrl": "https://ae01.alicdn.com/kf/H3ba2899c892d4a88a5f704453c39942ae/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg",
"productUrl": "https://www.aliexpress.com/item/S-XL-Plus-Size-Tunic-Autumn-Women-Dresses-Casual-Cartoon-Print-Christmas-Dress-Casual-Loose-Long/4000353066650.html",
"allImageUrls": "https://ae01.alicdn.com/kf/H3ba2899c892d4a88a5f704453c39942ae/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/H218b19ee8bfc4f6ebe74b4297ca8395f5/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/H14b48746d6eb4d5788a7a9f6ce37195c7/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/Hb4b1f8b6223d4e7c88208751bfa681886/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg,https://ae01.alicdn.com/kf/Hcfd17f95ac85470d9550d13f3683adc1I/S-XL-Plus-Size-Tunic-Autumn-font-b-Women-b-font-Dresses-Casual-Cartoon-Print-Christmas.jpg"
}
]
},
"errorCode": 20010000,
"currentPageNum": 0,
"totalPageNum": 0
}
var allImagesList = result.result.products[0].allImageUrls.split(',');
allImagesList.forEach((imageUrl)=>{
console.log(imageUrl);
})
And your code will look like something as below:
$(function (){
var $orders = $('#orders');
var $productimage = $('#productimage');
var $output = $('#output');
$.ajax({
type: 'GET',
url: 'http://gw.api.alibaba.com/openapi/param2/2/portals.open/api.listPromotionProduct/9420?fields=productUrl,allImageUrls,imageUrl,originalPrice,productTitle&keywords=women',
success: function(orders){
$.each(orders, function(i, order){
$orders.append('' + order.products[0].productTitle + '');
$output.append(order.products[0].allImageUrls[1]);
var allImagesList = order.products[0].allImageUrls.split(',');
allImagesList.forEach((imageUrl)=>{
$productimage.append('<img class="pic-1" src="' + imageUrl + '">'); // single image
})
});
}
});
});
$.each(orders, function(i, order) {
$orders.append('' + order.products[0].productTitle + '');
//------------------------Start
var allImageUrlsArray = []; // Create array;
//split with comma, assign to varaible and loop it.
allImageUrlsArray = order.products[0].allImageUrls.split(',');
for (var i = 0; i < allImageUrlsArray.length; i++) {
$output.append(allImageUrlsArray[i]);
}
//---------------------------End
});
You did some mistakes in iterate JSON Object, and allImageUrls contain multiple images with comma(,) so you should convert this into array. Let's check the below example
LN: 21 you can loop the allImageUrls
for([k, v] of Object.entries(value.allImageUrls)){
console.log(k, v);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="orders"></div>
<script>
$(function() {
var $orders = $('#orders');
var $productimage = $('#productimage');
var $output = $('#output');
$.ajax({
type: 'GET',
url: 'https://gw.api.alibaba.com/openapi/param2/2/portals.open/api.listPromotionProduct/9420?fields=productUrl,allImageUrls,imageUrl,originalPrice,productTitle&keywords=women',
success: function(item) {
let orders = item.result.products;
orders = orders.map(product => {
product.allImageUrls = product.allImageUrls.split(',');
return product;
});
var con = '';
for ([key, value] of Object.entries(orders)) {
con += "<li><a href='" + value.productUrl + "'><img style='width: 30px;' src='" + value.allImageUrls[0] + "'/>" + value.productTitle + "</a></li>";
// Loop all images
for ([k, v] of Object.entries(value.allImageUrls)) {
console.log(k, v);
}
}
$orders.append("<ul>" + con + "</ul>");
}
});
});
</script>
$(function() {
var $orders = $('#orders');
var $productimage = $('#productimage');
var $output = $('#output');
$.ajax({
type: 'GET',
url: 'http://gw.api.alibaba.com/openapi/param2/2/portals.open/api.listPromotionProduct/9420?fields=productUrl,allImageUrls,imageUrl,originalPrice,productTitle&keywords=women',
success: function(orders) {
$.each(orders.result.products, function(i, order) {
console.log(order)
$div = $('<div id = "' + "order_" + i + '"></div>');
$imageDiv = $('<div id = "' + "image_" + i + '"></div>');
// = $('#order_' + i);
console.log($div)
$div.append('' + order.productTitle + '');
//;
var array = order.allImageUrls.split(',');
for (var j = 0; j < array.length; j++) {
//$output.append(order.allImageUrls[j]);
$imageDiv.append('<img style="width:50px;height:50px" class="pic-1" src="' + array[j] + '">'); // single image
}
$div.append($imageDiv);
$orders.append($div);
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output">
<div id="orders">
</div>
</div>
Hope this helps. :)
I'm trying to create a loop to add multiple markers to an Leaflet map. One marker works, but when I try to do this with a loop, the markers don't work. I receive the data for the markers from a google spreadsheet.
$(document).ready(function() {
console.log("ready!");
// ID of the Google Spreadsheet
var spreadsheetID = "spreadsheetID";
// Make sure it is public or set to Anyone with link can view
var url = "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/1/public/values?alt=json";
$.getJSON(url, function(data) {
var entry = data.feed.entry;
var amount = entry.lenght;
var i;
for (i = 0; i <= amount; i++) {
var lat = data.feed.entry[i]['gsx$lat']['$t'];
var lon = data.feed.entry[i]['gsx$lon']['$t'];
var name = data.feed.entry[i]['gsx$name']['$t'];
var to = data.feed.entry[i]['gsx$to']['$t'];
var time = data.feed.entry[i]['gsx$time']['$t'];
var tel = data.feed.entry[i]['gsx$tel']['$t'];
var marker = L.marker([lon, lat]).addTo(mymap);
marker.bindPopup('<b>Name:</b> ' + name + '<br><b>To:</b> ' + to + '<br><b>Time:</b> ' + time + '<br><b> Tel:</b> ' + tel);
}
})
});
Your code with typo and LatLng problem fixed:
$(document).ready(function() {
console.log("ready!");
// ID of the Google Spreadsheet
var spreadsheetID = "spreadsheetID";
// Make sure it is public or set to Anyone with link can view
var url = "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/1/public/values?alt=json";
$.getJSON(url, function(data) {
var entry = data.feed.entry;
var amount = entry.length;
var i;
for (i = 0; i < amount; i++) {
var lat = data.feed.entry[i]['gsx$lat']['$t'];
var lon = data.feed.entry[i]['gsx$lon']['$t'];
var name = data.feed.entry[i]['gsx$name']['$t'];
var to = data.feed.entry[i]['gsx$to']['$t'];
var time = data.feed.entry[i]['gsx$time']['$t'];
var tel = data.feed.entry[i]['gsx$tel']['$t'];
var marker = L.marker([lat, lon]).addTo(mymap);
marker.bindPopup('<b>Name:</b> ' + name + '<br><b>To:</b> ' + to + '<br><b>Time:</b> ' + time + '<br><b> Tel:</b> ' + tel);
}
})
});
Well I'm trying to combine 2 examples to search from my geojson file, and when selected it will zoom that property.
Search (search in GeoJSON one) http://labs.easyblog.it/maps/leaflet-search/examples/
Zoom part from here (without the dropdown) http://projects.bryanmcbride.com/leaflet/select_zoom.html
Basically the first one just with zoom from second. I have been able to get them working, but separately.
Codes (1.)
var featuresLayer = new L.GeoJSON(piirid, {
style: function(f) {
return {color: f.properties.color };
}
});
map.addLayer(featuresLayer);
var searchControl = new L.Control.Search({layer: featuresLayer, propertyName: 'L_AADRESS', circleLocation:false});
searchControl.on('search_locationfound', function(e) {
e.layer.setStyle({fillColor: '#3f0', color: '#0f0'});
}).on('search_collapsed', function(e) {
featuresLayer.eachLayer(function(layer) { //restore feature color
featuresLayer.resetStyle(layer);
});
});
map.addControl( searchControl ); //inizialize search control
Code 2.
// Loop through the geojson features and extract bbox and name, then add the options to the "zoom" select (no jQuery)
/*var select = document.getElementById("zoom");
select.options[select.options.length] = new Option('Select a State', 'Select a State');
for (each in geojson._layers) {
var bbox = geojson._layers[each].getBounds()._southWest.lat + "," + geojson._layers[each].getBounds()._southWest.lng + "," + geojson._layers[each].getBounds()._northEast.lat + "," + geojson._layers[each].getBounds()._northEast.lng;
select.options[select.options.length] = new Option(geojson._layers[each].feature.properties.name, bbox);
}*/
// Loop through the geojson features and extract bbox and name, then add the options to the "zoom" select and build autocomplete(using jquery)
var options = '<option value="Select a State">Select a State</option>';
var states = [];
for (each in geojson._layers) {
var L_AADRESS = geojson._layers[each].feature.properties.L_AADRESS;
var swLat = geojson._layers[each].getBounds()._southWest.lat;
var swLng = geojson._layers[each].getBounds()._southWest.lng;
var neLat = geojson._layers[each].getBounds()._northEast.lat;
var neLng = geojson._layers[each].getBounds()._northEast.lng;
var bbox = swLat + "," + swLng + "," + neLat + "," + neLng;
// Populate states array and build autocomplete
states.push({label: L_AADRESS, value: L_AADRESS, swlat: swLat, swlng: swLng, nelat: neLat, nelng: neLng});
$( "#search" ).autocomplete({
source: states,
minLength: 3,
select: function( event, ui ) {
map.fitBounds([[ui.item.swlat, ui.item.swlng],[ui.item.nelat, ui.item.nelng]]);
}
});
// Add states & bbox values to zoom select options
options += '<option value="' + bbox + '">' + geojson._layers[each].feature.properties.L_AADRESS + '</option>';
}
If I understand your question correctly you just have to add:
map.fitBounds(e.layer.getBounds());
to the search_locationfound event function.
This will set the maximum zoom level that you can still see the whole layer.
So the search_locationfound event function from your first example would be:
searchControl.on('search_locationfound', function(e) {
map.fitBounds(e.layer.getBounds());
e.layer.setStyle({fillColor: '#3f0', color: '#0f0'});
});
jsfiddle
I have an RSS reader that fetches events with ajax. I want the user to be able to click the link of the event and have it transition to a new page with the details. Here is an example I found: http://jsfiddle.net/hellosze/t22QP/ I am have trouble understanding what is happening since I am rather new to jQuery so I was hoping someone code direct me as to what is happening. Thanks!
Here is how I extract the xml data and display it to a main page:
$.ajax({
type: 'GET',
url: 'categoryURL',
dataType: 'xml',
success: function (xml) {
var data = [];
$(xml).find("item:lt(40)").each(function () {
var dateText = $(this).find("Date").text().toString();
var eventDate = moment(dateText,"YYYY-MM-DD");
var title = $(this).find("title").text();
var region = dateText.substr(8).toUpperCase();
if (region.length < 3) { region = "ALL"; }
var description = $(this).find("description").text();
var dateDisplay = description.substr(0, description.indexOf(",")+6); //Parsed DATE from description
if (dateDisplay.length > 35) { dateDisplay = "See event for details"; }
//var locationdisplay = description.substr(description.indexOf(",")+6,4); //Parsed the location from description
var category = $(this).find("category").text();
var linkUrl = $(this).find("link").text();
var displayTitle = "<a href='" + linkUrl + "' target='_blank'>" + title + "</a>"
var item = {title: displayTitle, DateDecription: dateDisplay, Date: new Date(eventDate), Region: region,}
data.push(item);
// $('#feedContainer').append('<h3>'+displaytitle+'</h3><p>'+"Event Date: "+descriptdisplay+'</p><p>'+"Location: "+region+'</p');
}); //END .each()
data.sort(function (a, b) {
a = new Date(a.Date);
b = new Date(b.Date);
return a>b ? -1 : a<b ? 1 : 0;
});
$.each(data, function (index, item) {
$('#feedContainer').append('<h3>' + item.title + '</h3><p>' + "Event Date: " + item.DateDecription + '</p><p>' + "Location: " + item.Region + '</p');
});
} //END success fn
});
});
How can I force google to redraw its infoWindow or atleast refresh its contents?
I noticed that I must click twice on a marker before the correct data appears inside the infoWindow -maybe my closure here is the culprit.
var markers = new Array();
var allMarkers = new Array();
var infoWindow = new google.maps.InfoWindow();
var infoWindows = new Array();
// IE caches ajax request - need a way to clear cache with each fetch of data
randomize = function () {
var randomnumber = Math.floor(Math.random() * 100000);
return randomnumber;
}
function getBeachLocations() {
// construct query
var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql=";
var queryTail = "&key=apiKey&callback=?";
var query = "SELECT * FROM BeachTable"; // beach locations tbl
var queryText = encodeURI(query);
$.ajax({
type: "GET",
url: queryURL + queryText + queryTail,
cache: false,
dataType: 'jsonp',
success: createMarkers,
error: function () {
alert("Sorry, no spatial data is available at this time, please check back on a later date.");
}
});
} //end getBeachLocations
function createMarkers(data) { // =====================create markers
url = "http://swim.jpg";
var rows = data['rows'];
var ecoli_rows;
var algae_rows;
for (var m in rows) {
var ecoli_array = new Array();
var marker = new google.maps.Marker({
map: map,
icon: new google.maps.MarkerImage(url),
beach_id: rows[m][0],
beach_name: rows[m][1],
beach_region: rows[m][2],
position: new google.maps.LatLng(rows[m][4], rows[m][5]),
idx: m,
getHeader: function () {
var str = [
'<div style="width:650px;">',
'<div class="tabs">',
'<ul>',
'<li><span>E. Coli Data</span></li>',
'<li><span>Algae Data</span></li>',
'</ul>',
'<div id="tab-1">',
'<h1>' + this.beach_name + '</h1>',
'<h3>' + this.beach_region + '</h3>'
].join('');
return str;
}, // end getHeader method
getEcoliData: function () { // begin getEcoliData
var obj;
obj = getEcoliData(this.beach_id);
return obj;
}, // end getEcoliData method
afterGetEcoliData: function (data) {
var ecoli_rows;
var ecoli_rows_str;
ecoli_rows = data['rows'];
var ecoli_rows_str = [
'<table id="ecoli_table " class="data" style="width:500px;">',
'<tr>',
'<th>Sample Date</th>',
'<th>Average E. coli Density <br/> (200 cfu/100 ml)</th>',
'<th>Recreational Water Quality Guideline</th>',
'</tr>'
].join('');
if (typeof ecoli_rows == 'undefined') {
ecoli_rows_str = '<p>Sorry no ecoli data currently exists for this beach.</p></div>'
} else {
for (var i = 0; i < ecoli_rows.length; i++) {
//console.log(rows[i]);
ecoli_rows_str += '<tr><td>' + formatDate(ecoli_rows[i][2]) + '</td><td>' + checkEcoliCount(ecoli_rows[i][3]) + '</td><td>' + ecoli_rows[i][4] + '</td></tr>';
}
ecoli_rows_str += '</table>'
ecoli_rows_str += '</div>';
// remove after test
ecoli_rows_str += '<div id="tab-2"><h1>nothing loaded</h1></div></div></div>';
} //end if
return ecoli_rows_str;
}, // end outPutEcoliData method
getAlgaeData: function () { // begin getAlgaeData
var obj;
var algae_rows_str = [
'<div id="tab-2">',
'<h1>' + this.beach_name + '</h1>',
'<h3>' + this.beach_region + '</h3>',
'<table id="algae_table " class="data" style="width:500px;">',
'<tr>',
'<th>Sample Date</th>',
'<th>Algal Toxin Microcystin <br/> (20 ug/L)</th>',
'<th>Recreational Water Quality Guideline</th>',
'<th>Blue Green Algae Cells <br/>(100,000 cells/ml)</th>',
'<th>Recreational Water Quality Guideline</th>',
'</tr>'
].join('');
obj = getAlgaeData(this.beach_id);
return obj;
}, // end getAlgaeData method
outPutAlgaeData: function (data) {
obj.done(function (data) {
algae_rows = data['rows'];
}); // end success
//console.log(algae_rows);
if (typeof algae_rows === 'undefined') {
algae_rows_str = [
'<div id="tab-2">',
'<h1>' + this.beach_name + '</h1>',
'<h3>' + this.beach_region + '</h3>',
'<p>Sorry no algae data exists for this beach.</p>',
'</div>',
'</div>',
'</div>',
'</div>'
].join('');
} else {
for (var i = 0; i < algae_rows.length; i++) {
//console.log(rows[i]);
algae_rows_str += '<tr><td>' + formatDate(algae_rows[i][2]) + '</td><td>' + checkAlgaeToxinCount(algae_rows[i][3]) + '</td><td>' + algae_rows[i][4] + '</td><td>' + checkAlgaeCount(algae_rows[i][5]) + '</td><td>' + algae_rows[i][6] + '</td></tr>';
}
algae_rows_str += '</table>'
algae_rows_str += '</div></div></div>';
//return algae_rows_str;
} //end if
return algae_rows_str;
} // end outPutAlgaeData
}); // ====================end marker
allMarkers.push(marker); //required for drop down menu
console.log(marker.beach_id + " " + marker.beach_name);
// click event handler
google.maps.event.addListener(marker, 'click', function () {
var ajaxObj = this.getEcoliData();
var marker = this;
var str;
// add loading gif
//infoWindow.setContent('<img src="../img/loading.gif" alt="loading data"/>');
ajaxObj.done(function (data) {
/*
str = marker.getHeader() + marker.afterGetEcoliData(data);
console.log(str);
*/
infoWindow.setContent(marker.getHeader() + '' + marker.afterGetEcoliData(data));
infoWindow.open(map, this);
$(".tabs").tabs({ selected: 0 });
}); // End done
}); // End click event handler
} // end for loop foreach marker
checkAdvisory(); // determine where this needs to be called from.
} //end function createMarkers
// format date as January 1, 2013
function formatDate(num) {
var d = Date.parse(num).toString('MMMM d, yyyy');
return d;
}
// check ecoli count - anything greater than or equal to 200 cfu/100ml is flagged
function checkEcoliCount(num) {
var str;
num = parseFloat(num);
if (num >= 200) {
str = '<span class="ecoliCount_on" style="color:orange"><b>' + num + '</b></span>';
} else {
return num;
}
return str;
}
// check blue green algae count - anything greater than or equal to 100,000 cells/ml is flagged
function checkAlgaeCount(num) {
var str;
num = parseFloat(num);
if (num >= 100000) {
str = '<span class="algaeCount_on" style="color:orange"><b>' + num + '</b></span>';
} else {
return num;
}
return str;
}
// check algae toxin microcystin - anything greater than or equal to 20 ug/L is flagged
function checkAlgaeToxinCount(num) {
// why include < ? - ask Cassie
var str;
var idx;
idx = num.indexOf("<");
num = num.substring(idx + 1);
num = parseFloat(num);
if (num >= 20) {
str = '<span class="algaeToxinCountOn" style="color:orange"><br>' + num + '</b></span>';
} else {
return num;
}
return str;
}
function checkAdvisory() {
/* add advisory images
ecoliCount_on
algaeCount_on
algaeToxinCountOn
*/
$(".ecoliCount_on").each(function (i, v) {
console.log(i, v);
$(this).css("color", "green");
});
$(".algaeCount_on").each(function (i, v) {
console.log(i, v);
$(this).css("color", "green");
});
$(".algaeToxinCountOn").each(function (i, v) {
console.log(i, v);
$(this).css("color", "green");
});
}
function getEcoliData(beach_id) {
//console.log(beach_id);
var rows;
var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql=";
var queryTail = '&key=apiKey&callback=?';
var whereClause = "WHERE 'Beach_ID' = " + beach_id;
var query = "SELECT * FROM EcoliTable "
+ whereClause + " ORDER BY 'Sample_Date' DESC";
var queryText = encodeURI(query);
var ecoli_array = new Array();
return $.ajax({
type: "GET",
url: queryURL + queryText + queryTail,
cache: false,
dataType: 'jsonp'
});
}
function getAlgaeData(beach_id) {
var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql=";
var queryTail = '&key=apiKey&callback=?';
var whereClause = " WHERE 'Beach_ID' = " + beach_id;
var query = "SELECT * FROM algaeTable "
+ whereClause + " ORDER BY 'Sample_Date' DESC";
var queryText = encodeURI(query);
// ecoli request
return $.ajax({
type: "GET",
url: queryURL + queryText + queryTail,
cache: false,
dataType: 'jsonp'
});
}
// create beach locations dropdown
function createDropDownMenu() {
var query = 'SELECT Beach_Location, Beach_ID FROM beachTable ORDER BY Beach_Location ASC';
var queryText = encodeURIComponent(query);
var gvizQuery = new google.visualization.Query(
'http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
//Send query and draw table with data in response
gvizQuery.send(function (response) {
var numRows = response.getDataTable().getNumberOfRows();
var numCols = response.getDataTable().getNumberOfColumns();
var name = ['<label style="font-weight:bolder;font-size:16px"> Select a Beach:</label><select id="beach_menu" style="font-size:16px;" onchange="select_beach(this.options[this.selectedIndex].value);"><option class="defaultopt" value="">--All--</option>'];
for (var i = 0; i < numRows; i++) {
var nameValue = response.getDataTable().getValue(i, 0);
var idValue = response.getDataTable().getValue(i, 1);
name.push("<option value=" + "'" + idValue + "'" + ">" + nameValue + "</option>");
}
name.push('</select>');
document.getElementById('beach_location_dropdown').innerHTML = name.join('');
});
} // end createDropDownMenu Function
function select_beach(val) {
$("#beach_menu option[value='" + val + "']").attr('selected', 'selected');
if (val === "") {
resetMapExtent();
displayAllBeaches();
}
else {
update_layer(val)
}
} // end select_beach function
function resetMapExtent() {
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(53.760861, -98.813876));
map.setZoom(5);
} // end resetMapExtent function
// implement update_layer function
function update_layer(beach) {
infoWindow.close();
for (var z = 0; z < allMarkers.length; z++) {
if (beach === allMarkers[z].beach_id) {
allMarkers[z].setVisible(true);
} else {
// hide all other markers
allMarkers[z].setVisible(false);
}
}
} // end update_layer function
function displayAllBeaches() {
infoWindow.close();
// show all markers
for (var z = 0; z < allMarkers.length; z++) {
// hide all markers
allMarkers[z].setVisible(true);
}
} // end displayAllBeaches
/* start map initialization */
function initialize() {
// map
latlng = new google.maps.LatLng(49.894634, -97.119141);
var myOptions = {
center: latlng,
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeControl: true,
mapTypeControlOptions: {
mapTypeIds: [
google.maps.MapTypeId.ROADMAP,
google.maps.MapTypeId.SATELLITE,
google.maps.MapTypeId.HYBRID,
google.maps.MapTypeId.TERRAIN
],
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
overviewMapControl: true,
overviewMapControlOptions: {
opened: true
}
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// invocation begins here
createDropDownMenu(); // not working now.
getBeachLocations();
// legend
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(
document.getElementById('legend'));
var legend = document.getElementById('legend');
var swim_icon = "swim.jpg";
var div = document.createElement('div');
div.innerHTML = '<h4>Features</h4>' +
'<br/><img src="' + swim_icon + '"> ' + "Beaches";
legend.appendChild(div);
} // end initialization function
$(function () {
$('.view_normal').live('click', function () {
$(".container").css("width", "930px").css("margin", "auto");
$(".onewidecenter").css("width", "930px").css("margin", "auto");
$("#map_canvas").css("width", "930px").css("margin", "auto");
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(53.760861, -98.813876));
map.setZoom(5);
});
$('.view_full_screen').live('click', function () {
$(".container").css("width", "100%").css("margin", "auto");
$(".onewidecenter").css("width", "100%").css("margin", "auto");
$("#map_canvas").css("width", "100%").css("margin", "auto");
$(" #dropdown_container").css("width", "100%").css("margin", "auto");
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(53.760861, -98.813876));
map.setZoom(5);
});
}); // end page load
I have included the sample code above. Please pay special attention to my click event handler. As always, as suggestions on how best to remedy this would be greatly appreciated.
Thanks in advance,
Michael
jQuery AJAX methods are asynchronous. That means:
obj.success(function (data) {
ecoli_rows = data['rows'];
}); // end sucess
Returns immediately but the callback function doesn't run until the ajax request completes.
This means that:
infoWindow.setContent(this.getHeader() + '' +
this.getEcoliData() + '' + this.getAlgaeData());
infoWindow.open(map, this); //ajax callback hasn't fired here
opens the info window with the content BEFORE the ajax request completes.
To correct, you might do something like this:
In marker.getEcoliData:
obj = getEcoliData(this.beach_id);
return obj;
// move processing below this point to new method
And in the click event handler:
google.maps.event.addListener(marker, 'click', function () {
var ajaxObj = this.getEcoliData();
var marker = this;
ajaxObj.done(function() {
infoWindow.setContent(marker.getHeader() + '' +
marker.afterGetEcoliData() + '' +
this.getAlgaeData());
infoWindow.open(map, this);
$(".tabs").tabs({ selected: 0 });
});
This is not a complete solution since you have two asynchronous calls happening. You could either chain them, or set some kind of counter to make sure that the callback only executes when both have completed.
An even better approach would be to immediately open the infowindow with some kind of information to tell the user that data is being loaded. Then after the requests complete, you simply update the infowindow content again (with a handle to the content element) to show the returned data.
Thanks for the help with this. I managed to get this to work as expected. As it turned out I had to restructure the marker class so that two ajax requests weren't be returned an additional time.