show wfs attributes as label on selection - styles

I am trying to show attribute of wfs gml layer from geoserver as label in my openlayer3 application. I am successful to get label as text but unable to access the particular attribute 'name'. Given is the code I am working with.
var sourceWFS = new ol.source.Vector({
loader: function (extent) {
$.ajax('..../geoserver/harry/ows?', {
type: 'GET',
data: {
service: 'WFS',
version: '1.1.0',
request: 'GetFeature',
typename: 'ABC',
srsname: 'EPSG:3857',
geometryField:'geometry',
bbox: extent.join(',') + ',EPSG:3857'
}
}).done(function (response) {
sourceWFS.addFeatures(formatWFS.readFeatures(response));
});
},
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ()),
strategy: ol.loadingstrategy.bbox,
projection: 'EPSG:3857',
});
var layerWFS = new ol.layer.Vector({
source: sourceWFS
});
var interaction;
var interactionSelectPointerMove = new ol.interaction.Select({
condition: ol.events.condition.pointerMove
});
var interactionSelect = new ol.interaction.Select({
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255,0,0,1.0)',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.5)'
}),
text: new ol.style.Text({
text:("abcd")
})
})
});
var interactionSnap = new ol.interaction.Snap({
source: layerWFS.getSource()
});
I am getting abcd as label on selection

You will need a style function to set the text in the style from whichever feature property you wish to display
var selectStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255,0,0,1.0)',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.5)'
}),
text: new ol.style.Text({
text:("abcd")
})
});
var interactionSelect = new ol.interaction.Select({
style: function(feature) {
selectStyle.getText().setText(feature.get('name'));
return selectStyle;
}
});

You will not get any attribute that is "hidden" by a GML attribute by default. The most common "missing" attributes are name and id. You can turn off this (standard complying) behaviour by checking the Override GML Attributes in the WFS services page for the version of GML your client is requesting.

What you are actually displaying is the "abcd" string itself and not the value of "abcd" property.
To access some feature property value in an ol.Style you must use a StyleFunction as follows :
style: function(feature, resolution){
return new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255,0,0,1.0)',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.5)'
}),
text: new ol.style.Text({
text: feature.get("abcd");
})
})
}

Related

Joi Array Validation

Consider this code snippet. I want to query 'Markers' by 1 or many colors...
module.exports = [
{
method: 'GET',
path: '/search/markers',
options: {
auth,
description: 'Get Markers',
notes: 'Returns all marker info',
tags: ['api', 'markers'],
validate: {
query: {
color: Joi.array().items(Joi.string().valid('Red', 'Blue')).single().allow(''),
}
},
response: {
schema: MarkersValidation.getSearchMarkers
}
},
handler: SearchController.searchMarkers
}
];
exports.searchMarkers = async (request, h) => {
try {
const Markers = h.models().Markers;
const queryMarkers = Markers.query()
.select(h.knex().raw([
'markers.color'
]))
if (request.query.color) {
queryMarkers.andWhere(h.knex().raw(`color && '{${request.query.color}}'::text[]`));
}
}
}
catch (e) {
//error handler
}
}
However, I get the error below from Postman when I try to apply the query params of color with both Red, Blue. When I apply a single color param, for example: Red, it works fine.
Error
child "color" fails because [single value of "color" fails because ["color" must be one of [Red, Blue]]]
URL
{{url}}/search/markers?color=Red, Blue
Note
I tried removing .single(), but when I do, I get this error:
child "color" fails because ["color" must be an array]
Question
How do I resolve this?
Suppose I wanted a list of available colors to query by: 'Green', 'Purple', 'Yellow', 'Red', 'Blue'.
How would I add 1 or all of the options to the query?
Examples
{{url}}/search/markers?color=Red,
{{url}}/search/markers?color=Red, Blue, Yellow
This is my current code, but obviously doesn't work, any thoughts?
const myColors = ['Green', 'Purple', 'Yellow', 'Red', 'Blue'];
validate: {
query: {
color: Joi.array().items(Joi.string().valid(myColors)).single().allow(''),
}
}
UPDATED - SIMPLIFIED
In this image, I have an array with ".valid()" and the validation fails.
In this image, I have an array with no ".valid()" and the validation passes.
My Question
How can I add ".valid()" or something like it, to my Joi.array so that only the values I set are valid for this query?
You must pass the color query parameters as an array in your URL.
{{url}}/search/markers?color[]=Red&color[]=Blue
The joi schema to validate the color array:
const myColors = ['Green', 'Purple', 'Yellow', 'Red', 'Blue'];
joi.object().keys({
color: joi.array().items(myColors.map(col => col)),
});
const myColors = require('../data/colors');
const validateColors = (colors) => {
if (!colors) {
return true;
}
const colorsArray = colors.split(',');
const colorsSchema = Joi.array().items(Joi.string().valid(myColors)).allow('')
return Joi.validate(colorsArray, colorsSchema);
}
query: {colors: Joi.string().allow('')}

how to extract parameters from the context for list response using dialogflow fulfillment

Is it possible to pass the value of selected list item to any other intent. in my case I am passing a list and user select an item from the list, now I want to show this selected item name in another intent but I can't do that.
is anything wrong with my code
code runs properly only problem is instead of "selected item name" it returns "undefined".
this is my code
'use strict';
const functions = require('firebase-functions');
const {dialogflow, SimpleResponse} = require ('actions-on-google');
const {Suggestions, List, Image, BasicCard} = require ('actions-on-google');
const SHOW_PHONE_INTENT = 'Default Welcome Intent';
const FALLBACK_INTENT = 'Default Fallback Intent';
const SELECTED_PHONE_INTENT = 'SelectedPhoneIntent';
const ADD_TO_CART_INTENT = 'AddToCartIntent';
const AppContexts = {AWAITING_PHONE: 'awaiting-phone'};
const AppContexts1 = {AWAITING_REPLY: 'awaiting-reply'};
const app = dialogflow();
const PhoneDetail = {
'Phone1': {
text: `screen size = 5 inches \n
price = $100`,
subtitle: 'This is phone1',
title: 'Phone1 Details',
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'pic1',
}),
display: 'WHITE',
};
'Phone2': {
text: `screen size = 5.5 inches \n
price = $150`,
subtitle: 'This is phone2',
title: 'Phone2 Details',
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'pic2',
}),
display: 'WHITE',
};
'Phone3': {
text: `screen size = 6 inches \n
price = $200`,
subtitle: 'This is phone3',
title: 'Phone3 Details',
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'pic3',
}),
display: 'WHITE',
};
};
app.intent(FALLBACK_INTENT, (conv) => {
conv.ask("Sorry! Could you please repeat that?");
});
app.intent(SHOW_PHONE_INTENT, (conv) => {
conv.contexts.set(AppContexts.AWAITING_PHONE, 1);
conv.ask("Here's the list of phone's.");
conv.ask(new List({
title: "Select a phone to see details.",
items: {
"Phone1": {
title: "phone1",
description: "Click here to check phone1 details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'p1',
}),
},
"Phone2": {
title: "phone2",
description: "Click here to check phone2 details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'plc',
}),
},
"Phone3": {
title: "phone3",
description: "Click here to check phone3 details.",
image: new Image({
url: 'https://img.icons8.com/plasticine/2x/name.png',
alt: 'obj',
}),
},
},
}));
});
app.intent(SELECTED_PHONE_INTENT, (conv, input, option) => {
const context = conv.contexts.get(AppContexts.AWAITING_PHONE);
if (option) {
conv.ask(`${option} Details`);
conv.ask(new BasicCard(PhoneDetail[option]));
conv.ask(new Suggestions(['Show List', 'Add to Cart']));
} else {
conv.close('Sorry! there might be some issue, please contact support.');
}
conv.contexts.set(AppContexts1.AWAITING_REPLY, 1);
});
app.intent(ADD_TO_CART_INTENT, (conv, parameters) => {
const context1 = conv.contexts.get(AppContexts1.AWAITING_REPLY);
const selectedPhone = context1.parameters;
const qty = context1.parameters.qty;
if ('Add to Cart'){
let missingSlots = [];
if (!qty) { missingSlots.push('qty'); }
if (missingSlots.length === 1){
conv.ask(`How many phone's do you need?`);
} else {
conv.ask(`You have ordered ${qty} ${selectedPhone}. `);
conv.close("Thanks for shopping with us.");
}
} else {
conv.close('Sorry! there might be some issue, please contact support.');
}
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
let suppose user selects phone1 and orders 2 qty
then my response comes as "You have ordered 2 undefined. Thanks for shopping with us."
need help in getting the selected item name instead of undefined.
Here is the Intent that handles selecting the item from the list:
The issue is that you're not actually setting the parameters in the Context, so no values are preserved between the calls to your webhook.
In the SELECTED_PHONE_INTENT handler, the line should be something more like
conv.contexts.set(AppContexts1.AWAITING_REPLY, 5, {
phone: option
});
while in the ADD_TO_CART_INTENT handler, you would get this information with a line such as
const selectedPhone = context1.parameters.phone;

How to set output context for list options in dialogflow?

How do I give an output context to each item of a list ?
I am having trouble with handling the list options because the output context is not there.
For example in this code :
const meditatetrackList = () => {
const list = new List({
title: 'Choose a track.',
items: {
'healing water': {
title: 'Healing Water',
synonyms: ['healing water'],
image: new Image({
url: 'http://www.vstplanet.com/News/2016/Nature-sounds/Relaxing-nature-sounds.jpg',
alt: 'healing water',
}),
},
'elven forest': {
title: 'Elven Forest',
synonyms: ['elven' , 'forest' , 'elven forest'],
image: new Image({
url: 'https://scx2.b-cdn.net/gfx/news/2018/europeslostf.jpg',
alt: 'elven forest',
}),
},
'warm light' : {
title : 'Warm Light',
synonyms: ['warm','light','warm light'],
image: new Image({
url: 'https://www.socwall.com/images/wallpapers/37753-2000x1300.jpg',
alt: 'warm light',
}),
}
}
});
return list;
};
Okay, I am late here but I recently did this.
In this example code, I am returning a dropoff list of items
Util.js
getDropOffListCard: function(nearestDropOffResponse, agent) {
let objItem = {};
for (let index = 0; index < nearestDropOffResponse.length; index++) {
const element = nearestDropOffResponse[index];
let key = element.name.toUpperCase().replace(/ /g, "_");
let each = {
synonyms: [
'synonym 1',
'synonym 2',
'synonym 3',
],
title: element.name,
description: element.address + '\n' + element.distance + ' ' + element.unit,
image: new Image({
url: url + 'info-icon.png',
alt: 'Image alternate text',
})
};
objItem[key] = each;
}
agent.context.set({ // here set the context
name: 'global_context',
lifespan: 2,
parameters: {
dropLocationList: objItem
}
});
return new List({
title: 'Nearest drop off location',
items: objItem
});
}
app.js
intentMap.set("Nearest Drop Off Intent - yes", function(agent){
const conv = agent.conv();
conv.ask('Here are nearest drop off location. Where you can drop or pickup your parcel.');
conv.ask(trackingUtil.getDropOffListCard(nearestDropOffResponse, agent));
agent.add(conv);
});
Create another intent to handle this and add the event Google Assistant Option this event do the trick, it will send the selected option to your intent handler, where you can access the selected option as well as a list that we set in context.
intentMap.set("Nearest Drop Off Intent - yes - selected", function(agent){
const option_intent = agent.context.get('actions_intent_option');
const option_key = option_intent.parameters.OPTION;
const global_context = agent.context.get('global_context');
const selection = global_context.parameters.dropLocationList[option_key]
agent.add(selection.title);
agent.add(selection.description);
agent.add(trackingUtil.dropOffDetailCard(selection))
});

Unable to add game object via the "physics.add.existing" method

I am unable to add an existing object to my game
function create() {
const scene: Phaser.Scene = this
// scene.physics.add.image(400, 100, 'ball') THIS WORKS => BALL APEARS IN GAME
const ball = new Phaser.GameObjects.Image(scene, 400, 100, 'ball')
scene.physics.add.existing(ball) // nothing displays
}
What am I missing out on ?
I had the same problem, but then discovered I had to add it to both the scene and the physics manager, such as:
const ball = new Phaser.Physics.Arcade.Sprite(scene, 400, 100, 'ball');
this.add.existing(ball);
this.physics.add.existing(ball);
var config = {
width: 800,
height: 600,
type: Phaser.AUTO,
loader: {
baseURL: 'https://raw.githubusercontent.com/nazimboudeffa/assets/master/',
crossOrigin: 'anonymous'
},
parent: 'phaser-example',
physics: {
default: 'arcade'
},
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
function preload()
{
this.load.image('dude', 'sprites/phaser-dude.png')
}
function create ()
{
var dude = new Phaser.GameObjects.Sprite(this, 100, 100, 'dude')
this.add.existing(dude)
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.17.0/dist/phaser.min.js"></script>

Rendering JSP in ALLOY DIALOG

I am using ALLOY DIALOG in Liferay 6.0.5 as follows:
function countPopup(){
AUI().use('aui-dialog', 'liferay-portlet-url', function(A) {
var dialog = new A.Dialog({
title: 'Upload Details',
centered: true,
modal: true,
width: 500,
height: 400,
bodyContent:"testing",
}).render();
});
}
I am getting in popup " testing ". But Instead of "bodycontent" I want to forward to one jsp file where i have written some logic. How to do that?
You must "plug" another module to feed a.Dialog with article desired.
Try some like this:
AUI().use('aui-dialog', 'aui-io', function(A) {
var dialog = new A.Dialog({
title: 'Upload Details',
centered: true,
modal: true,
width: 500,
height: 400,
}).plug(A.Plugin.IO, {uri: 'your_url.html'}).render();
});
I know this is too much late to give answer to this question but here is the solution.
<%
User selUser = (User)request.getAttribute("user.selUser");
PortletURL popupURL = renderResponse.createRenderURL();
popupURL.setWindowState(LiferayWindowState.POP_UP);
popupURL.setParameter("jspPage","Your jsp page path here");
String popup = "javascript:xyzPopUp('"+ popupURL.toString() + "');";%>
<aui:script>
Liferay.provide(
window,
'xyzPopUp',
function(url) {
var A = AUI();
var portletURL="<%=themeDisplay.getURLManageSiteMemberships().toString()%>";
var dialog = new A.Dialog(
{
modal: true,
centered: true,
destroyOnClose: true,
draggable: true,
height: 150,
resizable: false,
title: 'your title here',
width: 200
}
).plug(
A.Plugin.IO,
{
uri:url
}
).render();
},
['aui-dialog']
);
</aui:script>
This will open the given jsp page in to popup.

Resources