POI in OpenLayer 3 - openlayers-3

If load points from KML file to vetor layer
var layerPOI = new ol.layer.Vector({
source: new ol.source.KML({
projection: projection,
url: 'data/KML/mydata.kml'
})
})
How can I do a complete listing of all loaded points (POIs) and loaded properties (from data/KML/mydata.kml)? I think, for example, into the table - in map view (display layer) I can is already
Thank you very much for answer

ol.source.KML has a method getFeatures() which gives you all features in your KML. Then you can use getProperties() or get() on the feature to read the properties.

(Partial) solution:
allPOIs = layerPOI.getSource().getFeatures();
// or if define a source separatly
// allPOIs = sourcePOI.getFeatures();
onePOI = allPOIs[0]; // first element in Array
propertiesOfOnePOI = onePOI.getKeys();
propertiesOfOnePOI.forEach(function (elementName, elementIndex){
console.log( "element index: " + elementIndex + " | element name: " + elementName + " | element value: " + onePOI.get(elementName) );
});
But the element GEOMTERY returns Object.
I try to getting additional information about point yet but I can not -
Also more tags from KML file - For example, point style - how to determine the displayed icon?
Please still help ;)

Related

Create jQuery ui dialog box for each row in a table

I am trying to append rows to a table using an array called searchResults. Everything works as expected until I introduce the jQuery UI dialog box. The problem is I need a new dialog box for each row in the first column. I'm pretty new to all of this so I'm pretty sure I'm using the index incorrectly at times. This is just to give you an idea of what I'm trying to accomplish. Any ideas how to do this correctly?
for (var i = 0; i < searchResults.length; i++)
{
$('#patientFileDialog[i]').dialog();
$'#openPFDialog[i]').click(function() {
$('#patientFileDialog[i]').dialog('open');
});
var dialog[i] = $(`<div id="patientFileDialog[i]" title="Patient File">${searchResults[i].patientWebLink}</div>`);
body.append('<tr>'+
`<td><button id="openPFDialog[i]">Click Here</button></td>` +
`<td>${searchResults[i].patientFirstName}</td>` +
`<td>${searchResults[i].patientLastName}</td>` +
`<td>${searchResults[i].patientDateOfBirth}</td>` +
`<td>${searchResults[i].patientDataPulseID}</td>` +
`<td>${searchResults[i].patientLaserFicheID}</td>` +
'</tr>')
}
After looking at your code a bit more I think I can see what you are trying to do. Working JSFiddle, with some faked searchResults so we can see it in action.
There are a few problems with the code in your question:
Using selectors like $('#patientFileDialog[i]') and $'#openPFDialog[i]') will try to match elements on the page with those IDs. AFAICT those don't actually exist yet, you are trying to create them.
var dialog[i] = ... sets up some divs as strings, but those are never added to the page;
As I mentioned in my comment, there are some syntax errors, maybe just typos and mixed up formatting here on SO;
Here's an updated version of the code. Notable changes:
Instead of adding an event handler for every individual openPFDialog button, it is better practice to add just one which matches them all. That single handler can then work out which button was clicked, and take the right action for just that one, not all of them. In this case if you have all your buttons use IDs that match openPFDialog-X, where X is a number, you can target anything matching that pattern (using a starts with selector, and find the X by removing the openPFDialog- part with replace.
There's an added complication with the above though. Selectors parsed at page load will only match elements that exist at that time. In this case, you're adding new elements to the page, and a selector defined at page load won't match them. The solution is to select instead some parent element which does exist at page load, and filter. This is called event delegation (search for the paragraph starting with "Delegated event handlers").
Working from what you have, I am guessing the patientFileDialogs you create should be placed inside some parent element which is not displayed on the page? That's what I've done.
Here's the code (and working JSFiddle):
var dialog, i;
// Single click handler for anything that starts with "openPFDialog-".
// Since those elements don't exist on the page yet, we need to instead
// select a parent object, say the body, and filter for clicks on our
// elements starting with our pattern
$('body').on('click', '[id^=openPFDialog]', function() {
// We need to find the "i"
i = $(this).attr('id').replace(/openPFDialog-/,'');
console.log('clicked on id', i);
$('#patientFileDialog-' + i).dialog();
});
for (var i = 0; i < searchResults.length; i++) {
// Create a new div with ID like "patientFileDialog-1", using the current
// search result
dialog = $('<div id="patientFileDialog-' + i + '" title="Patient File">' + searchResults[i].patientWebLink + '</div>');
// Add it to the page. I've use a div with ID dialogs which is hidden
$('#dialogs').append(dialog);
$('table').append('<tr>'+
'<td><button id="openPFDialog-' + i + '">Click Here</button></td>' +
'<td>' + searchResults[i].patientFirstName + '</td>' +
'<td>' + searchResults[i].patientLastName + '</td>' +
'<td>' + searchResults[i].patientDateOfBirth + '</td>' +
'<td>' + searchResults[i].patientDataPulseID + '</td>' +
'<td>' + searchResults[i].patientLaserFicheID + '</td>' +
'</tr>');
}
Update
One last suggestion - manipulating the DOM by adding/removing elements is slow. If you need to do that for each element in an array, it is best to avoid actually adding your content on each iteration, and rather just build up a string. Then once you're done iterating, just add the big single string, so you're chaning the DOM just once. Here's the basic changes needed to do that:
// Add some new variables to hold our big strings
var dialog, dialogs, row, rows, i;
// ... your code ...
for (var i = 0; i < searchResults.length; i++) {
// Create the dialog ...
dialog = ...
// Append it to our big string of all dialogs
dialogs += dialog;
// Same approach for rows
row = '<tr>'+ ... all that stuff
rows += row;
}
// Finished iterating, nothing added to DOM yet. Do it all at once::
$('#dialogs').append(dialogs);
$('table').append(rows);
Here is what I finally ended up having to do:
$(document).ready(function(){
if ($('[attr="searchResultsJson"]').length)
{
$('.approval-outer-wrap').prepend(drawTable());
$('.approval-outer-wrap').append('<div id="result-details" title="Search Result Detail"><p></p></div>')
}
$('body').on('click', '[id^=openPFDialog]', function() {
var result = $(this).parents('tr').data('result');
$('#result-details p').html(result.patientFirstName);
$('#result-details').dialog();
});
});
function drawTable(){
var table = $('<table id="search-results" />');
var header = $('<thead />');
table.append(header);
header.append('<tr><th>Patient File</th><th>First Name</th><th>Last Name</th><th>Date of Birth</th><th>Data Pulse ID</th><th>Laserfiche ID</th></tr>');
var body = $('<tbody />');
table.append(body);
var json = $('[attr="searchResultsJson"] [type="text"]').text();
var searchResults = JSON.parse(json);
for (var i = 0; i < searchResults.length; i++) {
body.append(`<tr data-result='${JSON.stringify(searchResults[i])}'>`+
`<td><button id="openPFDialog-` + i + `">🔍</button></td>` +
`<td>${searchResults[i].patientFirstName}</td>` +
`<td>${searchResults[i].patientLastName}</td>` +
`<td>${searchResults[i].patientDateOfBirth}</td>` +
`<td>${searchResults[i].patientDataPulseID}</td>` +
`<td>${searchResults[i].patientLaserFicheID}</td>` +
'</tr>');
}
return table;
}
Consider the following code.
function showPatientDialog(cnt){
$("#patient-file-dialog").html(cnt).dialog("open");
}
var d = $("<div>", {
id: "patient-file-dialog",
title: "Patient File"
})
.appendTo("body")
.dialog({
autoOpen: false
});
$.each(searchResults, function(i, result) {
var row = $("<tr>").appendTo(body);
$("<td>").appendTo(row).html($("<button>", {
id: "open-pdf-dialog-" + i
}).click(function() {
showPatientDialog(result.patientWebLink);
}));
$("<td>").appendTo(row).html(result.patientFirstName);
$("<td>").appendTo(row).html(result.patientLastName);
$("<td>").appendTo(row).html(result.patientDateOfBirth);
$("<td>").appendTo(row).html(result.patientDataPulseID);
$("<td>").appendTo(row).html(result.patientLaserFicheID);
});

Set a different tooltip formatter for each sunburst levels - Highcharts

I created a sunburst chart with highcharts. I set the config object given to Highcharts.chart('type', config) in python. I want to have one different tooltip for each level of the sunburst chart.
I can do a big js function that search the level of the point in my data then give the level to the tooltip formatter to display the specific data, but that is not suitable I think.
Is there any highcharts function to get the point's level or to define the tooltip in series.levels[]?
You could get this based upon the slice's level property. You can do something like:
tooltip: {
formatter: function () {
console.log(this); // see what each slice's properties are
if (this.point.node.level == 4) {
return 'Population of <b>' + this.point.options.name +
'</b> is <b>' + this.point.options.value + '</b>';
} else {
return 'Level <b>' + this.point.node.level + '</b> has no tooltip';
}
}
}
Example jsFiddle
Tank you for your answer wergled. In fact what help me is the console.log(this)! I don't know why but this refers directly to the point in my code. And since I code in python, I have to format a js function into a python string, this is quite difficult.
So I ended with something like:
config['tooltip']['pointFormatter'] = (
"function(){"
"var level = this.node.level;"
"return"
f" {myValues}[level] + '<span style=\"text-transform: uppercase;font-weight:bold\">{myPythonVar}:</span> '"
f"+ {myJsFormatter}.call(this) + '<br>'"
"}"
)
It mixes python and js, it hard to read but needed in my case.

addFeatures doesn't seem to be taken in my code

I'm working on openlayers 3 and ExtJS 6. I have a vector who is loaded with a GeoJson. I clear it and I want to add some new features once it's cleared.
My new data are provided by a store. So this is what I want to add in my vector :
[{"type":"Feature","properties":{"SCALERANK":6,"NATSCALE":30,"LABELRANK":5,"FEATURECLA":"Populated place","NAME":"Marsabit","NAMEPAR":null,"NAMEALT":null,"DIFFASCII":0,"NAMEASCII":"Marsabit","ADM0CAP":0,"CAPALT":0,"CAPIN":null,"WORLDCITY":0,"MEGACITY":0,"SOV0NAME":"Kenya","SOV_A3":"KEN","ADM0NAME":"Kenya","ADM0_A3":"KEN","ADM1NAME":"Eastern","ISO_A2":"KE","NOTE":null,"LATITUDE":2.329999,"LONGITUDE":37.979997,"CHANGED":1,"NAMEDIFF":0,"DIFFNOTE":"Changed scale rank.","POP_MAX":16460,"POP_MIN":15361,"POP_OTHER":16460,"RANK_MAX":6,"RANK_MIN":6,"GEONAMEID":187585,"MEGANAME":null,"LS_NAME":"Marsabit","LS_MATCH":1,"CHECKME":0,"MAX_POP10":16460,"MAX_POP20":16460,"MAX_POP50":0,"MAX_POP300":0,"MAX_POP310":0,"MAX_NATSCA":20,"MIN_AREAKM":12,"MAX_AREAKM":12,"MIN_AREAMI":5,"MAX_AREAMI":5,"MIN_PERKM":17,"MAX_PERKM":17,"MIN_PERMI":10,"MAX_PERMI":10,"MIN_BBXMIN":37.975,"MAX_BBXMIN":37.975,"MIN_BBXMAX":38.033333,"MAX_BBXMAX":38.033333,"MIN_BBYMIN":2.325,"MAX_BBYMIN":2.325,"MIN_BBYMAX":2.341667,"MAX_BBYMAX":2.341667,"MEAN_BBXC":38.004167,"MEAN_BBYC":2.333333,"COMPARE":0,"GN_ASCII":"Marsabit","FEATURE_CL":"P","FEATURE_CO":"PPL","ADMIN1_COD":3,"GN_POP":15361,"ELEVATION":0,"GTOPO30":1344,"TIMEZONE":"Africa/Nairobi","GEONAMESNO":"Geonames ascii name + lat.d + long.d matching.","UN_FID":0,"UN_ADM0":null,"UN_LAT":0,"UN_LONG":0,"POP1950":0,"POP1955":0,"POP1960":0,"POP1965":0,"POP1970":0,"POP1975":0,"POP1980":0,"POP1985":0,"POP1990":0,"POP1995":0,"POP2000":0,"POP2005":0,"POP2010":0,"POP2015":0,"POP2020":0,"POP2025":0,"POP2050":0,"CITYALT":null},"geometry":{"type":"Point","coordinates":[37.979996702838946,2.329998595077768]},"NAME":"Marsabit","id":"AIS_LIVE.model.PlacesModel-13153"},{"type":"Feature","properties":{"SCALERANK":7,"NATSCALE":20,"LABELRANK":3,"FEATURECLA":"Populated place","NAME":"Marsala","NAMEPAR":null,"NAMEALT":null,"DIFFASCII":0,"NAMEASCII":"Marsala","ADM0CAP":0,"CAPALT":0,"CAPIN":null,"WORLDCITY":0,"MEGACITY":0,"SOV0NAME":"Italy","SOV_A3":"ITA","ADM0NAME":"Italy","ADM0_A3":"ITA","ADM1NAME":"Sicily","ISO_A2":"IT","NOTE":null,"LATITUDE":37.805404,"LONGITUDE":12.438662,"CHANGED":0,"NAMEDIFF":0,"DIFFNOTE":null,"POP_MAX":77784,"POP_MIN":43179,"POP_OTHER":42587,"RANK_MAX":8,"RANK_MIN":7,"GEONAMEID":2524245,"MEGANAME":null,"LS_NAME":"Marsala","LS_MATCH":1,"CHECKME":0,"MAX_POP10":43179,"MAX_POP20":43179,"MAX_POP50":0,"MAX_POP300":0,"MAX_POP310":0,"MAX_NATSCA":20,"MIN_AREAKM":19,"MAX_AREAKM":19,"MIN_AREAMI":7,"MAX_AREAMI":7,"MIN_PERKM":25,"MAX_PERKM":25,"MIN_PERMI":16,"MAX_PERMI":16,"MIN_BBXMIN":12.425,"MAX_BBXMIN":12.425,"MIN_BBXMAX":12.491667,"MAX_BBXMAX":12.491667,"MIN_BBYMIN":37.766667,"MAX_BBYMIN":37.766667,"MIN_BBYMAX":37.816667,"MAX_BBYMAX":37.816667,"MEAN_BBXC":12.458631,"MEAN_BBYC":37.794643,"COMPARE":0,"GN_ASCII":"Marsala","FEATURE_CL":"P","FEATURE_CO":"PPL","ADMIN1_COD":15,"GN_POP":77784,"ELEVATION":0,"GTOPO30":7,"TIMEZONE":"Europe/Rome","GEONAMESNO":"Geonames ascii name + lat.d + long.d matching.","UN_FID":0,"UN_ADM0":null,"UN_LAT":0,"UN_LONG":0,"POP1950":0,"POP1955":0,"POP1960":0,"POP1965":0,"POP1970":0,"POP1975":0,"POP1980":0,"POP1985":0,"POP1990":0,"POP1995":0,"POP2000":0,"POP2005":0,"POP2010":0,"POP2015":0,"POP2020":0,"POP2025":0,"POP2050":0,"CITYALT":null},"geometry":{"type":"Point","coordinates":[12.43866166041903,37.805404275558374]},"NAME":"Marsala","id":"AIS_LIVE.model.PlacesModel-10722"},{"type":"Feature","properties":{"SCALERANK":4,"NATSCALE":50,"LABELRANK":3,"FEATURECLA":"Admin-1 region capital","NAME":"Marseille","NAMEPAR":null,"NAMEALT":"Marseille-Aix-en-Provence","DIFFASCII":0,"NAMEASCII":"Marseille","ADM0CAP":0,"CAPALT":0,"CAPIN":null,"WORLDCITY":0,"MEGACITY":1,"SOV0NAME":"French Republic","SOV_A3":"FRA","ADM0NAME":"France","ADM0_A3":"FRA","ADM1NAME":"Provence-Alpes-C-te-d'Azur","ISO_A2":"FR","NOTE":null,"LATITUDE":43.289979,"LONGITUDE":5.37501,"CHANGED":4,"NAMEDIFF":0,"DIFFNOTE":"Changed feature class.","POP_MAX":1400000,"POP_MIN":794811,"POP_OTHER":813666,"RANK_MAX":12,"RANK_MIN":11,"GEONAMEID":2995469,"MEGANAME":"Marseille-Aix-en-Provence","LS_NAME":"Marseille","LS_MATCH":1,"CHECKME":0,"MAX_POP10":946129,"MAX_POP20":1034294,"MAX_POP50":1034294,"MAX_POP300":0,"MAX_POP310":0,"MAX_NATSCA":50,"MIN_AREAKM":285,"MAX_AREAKM":361,"MIN_AREAMI":110,"MAX_AREAMI":140,"MIN_PERKM":237,"MAX_PERKM":327,"MIN_PERMI":147,"MAX_PERMI":203,"MIN_BBXMIN":5.158333,"MAX_BBXMIN":5.183333,"MIN_BBXMAX":5.633333,"MAX_BBXMAX":5.633333,"MIN_BBYMIN":43.216667,"MAX_BBYMIN":43.216667,"MIN_BBYMAX":43.466123,"MAX_BBYMAX":43.525,"MEAN_BBXC":5.397504,"MEAN_BBYC":43.351337,"COMPARE":0,"GN_ASCII":"Marseille","FEATURE_CL":"P","FEATURE_CO":"PPLA","ADMIN1_COD":0,"GN_POP":794811,"ELEVATION":0,"GTOPO30":54,"TIMEZONE":"Europe/Paris","GEONAMESNO":"Geonames ascii name + lat.d + long.d matching.","UN_FID":187,"UN_ADM0":"France","UN_LAT":43.28,"UN_LONG":5.38,"POP1950":756,"POP1955":798,"POP1960":929,"POP1965":1069,"POP1970":1182,"POP1975":1253,"POP1980":1295,"POP1985":1307,"POP1990":1305,"POP1995":1331,"POP2000":1357,"POP2005":1386,"POP2010":1400,"POP2015":1418,"POP2020":1445,"POP2025":1469,"POP2050":1490,"CITYALT":"Marseille"},"geometry":{"type":"Point","coordinates":[5.37306427182989,43.29192492260455]},"NAME":"Marseille","id":"AIS_LIVE.model.PlacesModel-13925"}]
But if I execute: me.getData('myVector').getSource().addFeatures(myData)
I've got an error.
I also tried
var format = new ol.format.GeoJSON();
me.getData('myVector').addFeatures(format.readFeatures( myData, {
featureProjection: 'EPSG:3857'
} ) );
It gives me 0 error but I when I want to display all my features there is nothing in my vector.
How can I do?

Build Map from String

I use Process.run where I execute an ldapsearch. Then, I get a String from stdout that look like this:
user: demo
first-name: demo
picture: trewtrewtrwrwgr
grewgrwgrwgrewgrwegrwe==
Can I do simply a Map from existing method, or I have to make one ?
Thank you.
To convert your entry :
String datas = '''user: demo
first-name: demo
picture: trewtrewtrwrwgr
grewgrwgrwgrewgrwegrwe==''';
final lines = datas.split('\n').fold([], (List<String> lines, line) {
if (line.contains(':')) lines.add(line);
// merge line that does not contain ":" with the previous
else lines.add(lines.removeLast() + '\n' + line);
return lines;
});
final m = new Map.fromIterable(lines.map((e) => e.split(':')),
key: (e) => e[0].trim(),
value: (e) => e[1].trim());
Never tried : you can also use dartdap (An LDAP Client Library for Dart).

Display dijit toolTip with Dojo DataGrid and JSonRestStore

Is there a more efficient way for displaying a tool tip once a cell is hovered? Using the structure attribute to format the datagrid, is there a way to use formatter to display a dijit toolTip rather than using the html title attribute.
Here is the column in which the toolTip is displaying.
var subscriberGridLayout = [
{
name: " ",
field: "ExpirationDate",
formatter: function(value){
if(value){
expDate = formatDateIE(value);
return toolTip();
}
else
return " ";
},
styles: "text-align: center;",
width: "30px"
},
Here is the function that displays a tooltip icon through the image tag but instead of a dijit toolTip it simply uses html's title to display a popup.
function toolTip(){
src = "'/Subscriber/resources/images/icons/icon_error.gif'/>";
if(dojo.date.difference(today, expDate) <= 0 ){
message = "Credential expired.";
return "<img title='"+ message + "' src=" + src + "";
} else if(dojo.date.difference(today, expDate) <= 60) {
message = "This Subscriber will expire in " + dojo.date.difference(today, expDate) + " days."
+ "
To prevent an interruption in the Subscriber’s access, please sumbit a request to " +
"renew the Subscriber within 30 days of the expiration date.";
return "<img title='"+ message + "' src=" + src + "";
} else {
return " ";
}
}
I would do something like:
new Tooltip({
connectId: grid.domNode,
selector: "td",
getContent: function(matchedNode){
return matchedNode.innerText
}
});
With grid.domNode you can get the generated DOM of your widget. A grid generates a table-structure, so you can get the cells by using the selector and getContent properties.
I must say it's not really the correct way to do it because now you're playing with the internal structure of the Dojo widget. If they once decide not to use a table as DOM structure your code won't work.
But I don't think there is a better way to achieve this, in the end you will always have to translate the Dojo cell to a DOM node (because tooltips are DOM based). You can of course connect a tooltip to each cell, but I tried that before and it was a little buggy (sometimes the tooltip didn't pop up).
I also made a JSFiddle to show you a working example.

Resources