QWebEngineView not load Openlayers - qt

I have tried to do a basic example with QWebEngineView and Openlayers but it does not work.
My steps:
I created the basic example in HTML from Openlayers
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/build/ol.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<h2>My Map</h2>
<div id="map" class="map"></div>
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([37.41, 8.82]),
zoom: 4
})
});
</script>
</body>
</html>
This works on Chrome.
I created a new Project in QT with webenginewidgets in pro file. In MainWindow, I put the following code:
QWebEngineView *view = new QWebEngineView(parent);
view->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
view->page()->settings()->setAttribute(QWebEngineSettings::AutoLoadImages, true);
view->page()->settings()->setAttribute(QWebEngineSettings::AllowGeolocationOnInsecureOrigins, true);
view->page()->settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, true);
view->page()->settings()->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, true);
view->load(QUrl::fromLocalFile("C:/TEST/test_webeng/openlayers.html"));
view->show();
I tried to put all these attributes because without them I get messages of this type:
Access to image at 'https://a.tile.openstreetmap.org/4/10/8.png' from origin 'file: //' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ", Source: file: /// C: /TEST/test_webeng/openlayers.html
With or without attributes, the map images are not displayed.
Any solution?

The problem is similar to the one in this post but with openlayers instead of openstreetmap, so the solution is to create a QWebEngineUrlRequestInterceptor that injects the Accept-Language header.
class Interceptor: public QWebEngineUrlRequestInterceptor{
public:
using QWebEngineUrlRequestInterceptor::QWebEngineUrlRequestInterceptor;
void interceptRequest(QWebEngineUrlRequestInfo & info){
info.setHttpHeader("Accept-Language", "en-US,en;q=0.9,es;q=0.8,de;q=0.7");
}
};
Interceptor *interceptor = new Interceptor(view);
view->page()->profile()->setUrlRequestInterceptor(interceptor);
view->load(QUrl::fromLocalFile("C:/TEST/test_webeng/openlayers.html"));

Related

Botframework with WordPress

I want to implement BotFramework in a WordPress but in any way or form, it's not working properly.
I used different scripts but got to the same wrong result.
one:
<script>
(function () {
var div = document.createElement("div");
document.getElementsByTagName('body')[0].appendChild(div);
div.outerHTML = "<div id='botDiv' style='height: 38px; position: fixed;
bottom: 0; z-index: 1000; background-color: red'>
<div id='botTitleBar' style='height: 38px; width: 400px;
position:fixed; cursor: pointer;'></div>
[advanced_iframe src="https://webchat.botframework.com/embed/..."
width="100%" height="600"]</div>";
document.querySelector('body').addEventListener('click', function (e) {
e.target.matches = e.target.matches || e.target.msMatchesSelector;
if (e.target.matches('#botTitleBar')) {
var botDiv = document.querySelector('#botDiv');
botDiv.style.height = botDiv.style.height == '600px' ? '38px' : '600px';
};
});
}());
</script>
it's giving me the banner but not opening the chat when pressed.
in other case the script:
<!DOCTYPE html>
<html>
<body>
<div id="webchat" role="main"></div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token: 'key' }),
userID: 'YOUR_USER_ID',
username: 'Web Chat User',
locale: 'en-US',
botAvatarInitials: 'WC',
userAvatarInitials: 'WW'
}, document.getElementById('webchat'));
</script>
</body>
</html>
but in this case, it's doing nothing.
help, please :(
I don't know how your environment is structured, so hopefully, this translates but I was able to accomplish this. I'm running this locally having spun up a WP site on a WAMP server.
First, I generate a token by making an API call to
https://directline.botframework.com/v3/directline/tokens/generate.
If you're already generating a token, then skip to the next section. If not, you can reference this code, found here (if of interest).
On WP, I am using a plugin called 'WP Coder' This allows you to enter in the necessary components while letting the plugin 'make it work' in the page. I tried hand-coding it in, but the WP page wasn't playing nice and this plugin was.
Once the plugin is installed, put this in the 'HTML code' section:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>WebChat</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="webchat" role="main"></div>
</body>
</html>
Followed by this in the 'CSS code' section:
html,
body {
height: 100%
}
body {
margin: 0
}
#webchat,
#webchat>* {
height: 500px;
width: 100%;
}
Btw, if you set the height to 100% for '#webchat' the chat will continuously scroll down the page, as entries are made, forcing the user to have to 'scroll after it'. Outside of that, adjust it as you will.
Under 'JS Code', add the following. Please note, that I'm generating a token locally. You will need to update this to match your method of token generation:
( async function () {
const res = await fetch( 'http://localhost:3979/directline/token', { method: 'POST' } );
const { token } = await res.json();
window.WebChat.renderWebChat( {
directLine: window.WebChat.createDirectLine( { token } )
}, document.getElementById( 'webchat' ) );
} )();
Next, under 'Include files' enter the two following JS files as URLs (individually):
https://unpkg.com/markdown-it/dist/markdown-it.min.js
https://cdn.botframework.com/botframework-webchat/master/webchat.js
Lastly, take the Publish 'shortcode' (mine looks like this [WP-Coder id="1"]) and place it on your page. This is found in the WP Coder plugin.
At this point, it should work for you. If not, I would look closely at how you are generating and passing the token.
Hope of help!

How to do internalisation for the labels in `change view` drop down?

How to do internalisation for the labels in change view drop down?
Trying to do in JavaScript.
Please refer to https://developer.here.com/api-explorer/maps-js/v3.0/maps/map-multi-language-support. Below is the sample code for a map with change view in Chinese.
Code Snippet for providing the language:
var ui = H.ui.UI.createDefault(map, defaultLayers, 'zh-CN');
Entire Sample Code:
Map at a specified location
Display a map at a specified location and zoom level
This example displays a movable map initially centered on the Brandenburg Gate in the centre of Berlin (52.5159°N, 13.3777°E)
Code
The map.setCenter() method and map.setZoom() method are able to control the location of the map.
JavaScript
JS + HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="UTF-8" >
/**
* Moves the map to display over Berlin
*
* #param {H.Map} map A HERE Map instance within the application
*/
function moveMapToBerlin(map){
map.setCenter({lat:52.5159, lng:13.3777});
map.setZoom(14);
}
/**
* Boilerplate map initialization code starts below:
*/
//Step 1: initialize communication with the platform
var platform = new H.service.Platform({
app_id: 'devportal-demo-20180625',
app_code: '9v2BkviRwi9Ot26kp2IysQ',
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
//Step 2: initialize a map - not specificing a location will give a whole world view.
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map, {pixelRatio: pixelRatio});
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers, 'zh-CN');
// Now use the map as required...
moveMapToBerlin(map);
</script>
</body>
</html>

Enyo error: "Uncaught referenceError: App is not defined"

I am getting the error: "Uncaught referenceError: App is not defined" in my JS console when loading this Enyo app on my localhost. I am brand new to Enyo so I am still trying to learn the concepts of kinds and components.
app.js (in source folder):
enyo.kind({
name: "App",
kind: "FittableRows",
classes: "enyo-fit enyo-unselectable",
components: [
{
kind: "onyx.Toolbar",
layoutKind:"FittableColumnsLayout",
components: [
{
kind:onyx.Button,
style:"width:80px;background:green;",
ontap:"handleBtnBack",
content:"Back"
},
{
content:"Header",
style:"text-align:center;",
fit:true
},
{
kind:onyx.Button,
style:"width:80px;background:red;",
ontap:"handleBtnNext",
content:"Next"
}
]
},
{
kind: "Scroller",
horizontal:"hidden",
touch:true,
fit:true,
thumb:true,
components:[
{
tag:"h1",
//This is how we insert css class.
classes:"padding15px",
content:"This is content area...Hello World!!!"
}
]
},
{
kind: "onyx.Toolbar",
// The footer
layoutKind:"FittableColumnsLayout",
components:[
{
kind:"onyx.Button",
content:"Go Next Page",
ontap:"handleBtnNextPage",
fit:true
}
]
}
],
create: function(){
this.inherited(arguments);
console.log("App is created in memory");
},
rendered : function(){
this.inherited(arguments);
console.log("App is created in rendered into DOM");
},
handleBtnNextPage : function(inSender,inEvent){
new Page2().renderInto(document.body);
},
handleBtnNext: function(inSender,inEvent){
new Page2().renderInto(document.body);
},
handleBtnBack: function(inSender,inEvent){
//For each enyo event handler comes with inSender, the control that sends the event and the inEvent the actual event itself.
alert("Back Button");
}
});
package.js (in source folder):
enyo.depends(
// Layout library
"$lib/layout",
// Onyx UI library
"$lib/onyx", // To theme Onyx using Theme.less, change this line to $lib/onyx/source,
//"Theme.less", // uncomment this line, and follow the steps described in Theme.less
// CSS/LESS style files
"../assets/css/app.css",
// Include our default entry point
"App.js",
"Page2.js"
);
index.html (in root folder):
<!--My Copy-->
<!DOCTYPE html>
<html>
<head>
<title>IsGoodStuff.com Tutorial #2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="shortcut icon" href="assets/favicon.ico"/>
<script src="enyo/enyo.js" type="text/javascript"></script>
<!-- -->
<script src="package.js" type="text/javascript"> </script>
</head>
<body>
<script type="text/javascript">
new App().renderInto(document.body);
</script>
</body>
</html>
If your index.html is in your root folder, but the main package.js is in the source folder, it's probably your script tag that loads package.js. Try:
<script src="source/package.js" type="text/javascript"> </script>
You haven't supplied Page2 but it appears the code would work as-is.
Here's a fiddle showing the working page: http://jsfiddle.net/kgxvg7Lw/1/
Some thoughts:
1) Are you using a case-sensitive file system? You show app.js but your package.js has App.js (capitalized).
2) Are you certain there are no parse errors in the console?
Now, that said... You probably don't want to reload a new app for every 'page' switch. Usually, you would use something like Panels to allow the app to control the content that appears on the screen and just navigate among the panels as needed.

is it possible to have the 4 zoom level feature with IE9 and IE10?

Using IE7, when hovering or clicking on the Zoombar, 4 zoom levels appears: Street, Country, Suburb, and State.
This features does not exist when I am using IE9 or IE10.
My question is how can I have this feature with IE9 and IE10?
The ZoomBar you are after is a legacy component which is only maintained on older browsers, modern browsers will automatically display the newer, smaller zoom component. Your only way to duplicate the older functionality here would be to create your own custom component through injecting a extra styled <DIV> element into the DOM.
Here is an example below combining the HERE Maps API with jQuery. Insert your app_id and app_code as necessary.
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9; IE=10" />
<script type="text/javascript" charset="UTF-8" src="http://js.cit.api.here.com/se/2.5.3/jsl.js?with=all"></script>
<script type="text/javascript" charset="UTF-8" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" charset="UTF-8" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" />
</head>
<body>
<h1>Adding an Overlay to the map</h1>
<div id="mapContainer" style="width:540px; height:334px;"></div>
<script id="example-code" data-categories="overlay" type="text/javascript" >
nokia.Settings.set("app_id", "YOUR APP ID");
nokia.Settings.set("app_code", "YOUR APP CODE");
// Use staging environment (remove the line for production environment)
nokia.Settings.set("serviceMode", "cit");
function extend(B, A) {
function I() {}
I.prototype = A.prototype;
B.prototype = new I();
B.prototype.constructor = B;
}
function HtmlControl (html, id) {
nokia.maps.map.component.Component.call(this);
this.init(html, id);
}
extend(HtmlControl,
nokia.maps.map.component.Component);
HtmlControl.prototype.init = function (html, id) {
that = this;
that.id = id
that.set("node", document.createElement("div"));
that.node.innerHTML = html;
};
HtmlControl.prototype.getId = function() {
return "HtmlControl." + this.id;
};
HtmlControl.prototype.attach = function(map) {
map.getUIContainer().appendChild(this.node);
};
HtmlControl.prototype.detach = function(display) {
map.getUIContainer().removeChild(this.node);
};
// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
// initial center and zoom level of the map
center: [52.51, 13.4],
zoomLevel: 10
});
htmlControl = new HtmlControl(
"<div id='slider' style='left:4em;top:1em;width:10px;min-height:250px'/></div>", "Sidebar");
map.components.add(htmlControl);
setUpSlider();
function setUpSlider(){
$( "#slider" ).slider({
// range: true,
min: 0,
max: 20,
orientation: "vertical",
value: 10,
slide: function( event, ui ) {
map.set("zoomLevel", ui.value);
}
});
$( "#slider" ).slider( "value", 10 );
}
</script>
</body>
</html>
The custom ZoomBar can be seen below:
You can add further CSS styles to the HTML as you see fit, for example:
htmlControl = new HtmlControl(
"<div style='position:absolute'>" +
"<div id='slider' style='float:left;left:1em;top:1em;width:10px;min-height:200px;'></div> " +
"<div style='left:5em;min-width:150px;;min-height:200px;float:left; background:url(labels.png) no-repeat'></div>" +
+ "</div>", "Sidebar");
map.components.add(htmlControl);
where labels refers to:
will display additional labels. This would obviously be better left in a CSS stylesheet of course.

How to preserveViewport with Drive KML file embed in google maps api v3

EDIT: Solved:
var opt = { minZoom: 6, maxZoom: 9 };
map.setOptions(opt);
I'm a cut-and-paste coder and while I intend on learning the syntax better, I'm on a deadline for now so I'm asking for help. I have googled extensively and while there are solutions to my problem, I haven't found one that works for me. My KML file is hosted on Google Drive so instead of a file url there is a driveFileId.
If you want to preserveViewport, you normally just add it to the layer object and set it to 'true'. However my KML file won't let me override its default zoom level where the bounds fit the screen no matter how I write it. Can someone help? This is the working object:
var layer = new google.maps.KmlLayer({
driveFileId: "0Bexampleg"});
layer.setMap(map);
EDIT: Here's the whole thing. Perhaps you can see if there are redundancies or contradictions that are causing this.
<!DOCTYPE html>
<html<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=Aexamplekey0&sensor=true"></script>
<style>
#map {
width: 310px;
height: 410px;
}
</style>
<script>
window.onload = function () {
var latlng = new google.maps.LatLng(53.385873, -1.471471);
var styles = [
{
//whatever
}
]
var myOptions = {
zoom: 15,
disableDefaultUI: false,
styles: styles
},
map = new google.maps.Map(document.getElementById('map'), myOptions);
var layer = new google.maps.KmlLayer({
driveFileId: "0Bexampleg"});
layer.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
Based on the current release API documentation, you should be able to set the preserveViewport option in the object you instantiate:
var layer = new google.maps.KmlLayer({
driveFileId: "0Bexampleg",
preserveViewport: true});
layer.setMap(map);
Without further information, such as a URL to your KML data, information about your map center and zoom, there's not much further that can be said.
GOT IT!
Here it is:
var opt = { minZoom: 11, maxZoom: 15 };
map.setOptions(opt);
And then in your the myOptions object you set your default zoom. Solution found here: Google Maps v3 - limit viewable area and zoom level
thanks to #ChrisV. I don't know why but the KML Layer won't allow any permutation of the original preserveViewport code.

Resources