I try to visualize a WFS (from MapServer) in OL5.
The WFS works well (I can implement it without any problems in QGIS).
Also a request like:
http://blablabla/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=Flurstueckepunkt&srsname=EPSG:25832&bbox=411554,5791886,411677,5792008
gives me a nice gml-Output in epsg: 25832.
I try to implement it in OpenLayers like:
var vectorSource = new VectorSource({
format: new WFS(),
loader: function(extent, resolution, projection) {
var url = 'http://blablabla/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=ms:Flurstueckepunkt&srsname=EPSG:25832&bbox=412200,5791337,413600,5791800,EPSG:25832'
fetch(url).then(function(response) {
return response.text();
}).then(function(text) {
var features = vectorSource.getFormat().readFeatures(text);
// Add parsed features to vectorSource
vectorSource.addFeatures(features);
}).catch(function(error) {
alert(error.message);
})
}
});
var WFSLayer =new VectorLayer(
{
source: vectorSource,
projection: 'EPSG:25832',
style: new Style({ fill: new Fill({ color: 'yellow' })
})
});
var view = new View({
center: [rechtswert,hochwert],
zoom: mzoom,
projection: 'EPSG:25832'
});
var map = new Map({
layers: [osm,wmsLayer2,WFSLayer],
target: 'map',
view: view
});
...but the WFS-Layer is not shown at all.
Via the Mozialle-Debugger I can see, that the wfs-request workes, but nothing is visualized?
Has anybody an idea what is wrong here?
Allright, I got it. As the WFS ist delivering points the visualisation-style is important.
It workes now with:
var vectorSource = new Vector({
format: new GML3(),
loader: function(extent) {
var url = 'http://blablalbvlAn/cgi-bin/mapserv?service=WFS&version=1.1.0&request=GetFeature&typename=ms:Flurstueckepunkt&srsname=EPSG:25832&' +
'bbox='+ extent.join(',') +',EPSG:25832';
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function() {
vectorSource.removeLoadedExtent(extent);
}
xhr.onerror = onError;
xhr.onload = function() {
if (xhr.status == 200) {
vectorSource.addFeatures(
vectorSource.getFormat().readFeatures(xhr.responseText));
var features3 = vectorSource.getFeatures();
} else {
onError();
}
}
xhr.send();
},
strategy: bbox
});
var WFSLayer =new VectorLayer(
{
source: vectorSource,
style: new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({
color: 'orange'
})
})
})
});
Related
Good Morning.
To work with wfs layer is it better to use leaflet or openlayers?
I have a code with openlayers that returns WFS from the geoserver. But I'm not able to show the attributes in popup. can anybody help me?
Thanks
You can try ol-ext ol/Overlay/PopupFeature to display feature attributes in a popup.
See example: https://viglino.github.io/ol-ext/examples/popup/map.popup.feature.html
Following the example of https://viglino.github.io/ol-ext/examples/popup/map.popup.feature.html, I have this code where my WFS layer contains the id and name attributes, however, it doesn't show anything in the popup
var vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent) {
return 'http://localhost:8080/geoserver/teste/wfs?service=WFS&' +
version=1.1.0&request=GetFeature&typename=teste:MYLAYER&' +
'outputFormat=application/json&srsname=EPSG:4326&' +
'bbox=' + extent.join(',') + ',EPSG:4326';
},
strategy: ol.loadingstrategy.bbox
});
var vector = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 255, 1.0)',
width: 2
})
})
});
var layers = [
new ol.layer.Tile({source: new ol.source.OSM()}),
vector,
];
var map = new ol.Map({
layers: layers,
interactions: ol.interaction.defaults({ altShiftDragRotate:false, pinchRotate:false }),
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([-46.444137, -23.713596]),
zoom: 12
})
});
var select = new ol.interaction.Select({
hitTolerance: 5,
multi: true,
condition: ol.events.condition.singleClick
});
map.addInteraction(select);
var popup = new ol.Overlay.PopupFeature({
popupClass: 'default anim',
select: select,
canFix: true,
template: {
title:
function(f) {
return f.get('nome')+' ('+f.get('id')+')';
},
attributes: // [ 'id', 'nome' ]
{
'nome': { title: 'Nome' },
'id': { title: 'Id' },
}
}
});
map.addOverlay (popup);
This is the popup code. I have 3 layers: layer1, layer2 and layer3.
For layer1, ID I want to show as ID. For layer2, I want to show ID as CODE and for other layers I don't want to show ID attribute.
How should I change the template? Thanks
var popup = new ol.Overlay.PopupFeature({
popupClass: 'default anim',
select: select_interaction,
canFix: true,
template: {
title:
function(f) {
return f.get('NAME')+' ('+f.get('ID')+')';
},
attributes:
{
'ID': { title: 'ID' },
// with prefix and suffix
'POP': {
title: 'População', // attribute's title
before: '', // something to add before
format: ol.Overlay.PopupFeature.localString(), // format as local string
after: ' hab.' // something to add after
},
}
}
});
#user12538529
You have to create a function and return the template for each case:
// Create templates
var templateID = { ... };
var templateCODE = { ... };
// Popup with a template function
var popup = new ol.Overlay.PopupFeature({
popupClass: 'default anim',
select: select_interaction,
canFix: true,
template: function(feature) {
var prop = feature.getProperties();
// Test if has property ID
if (prop.hasOwnProperty('ID')) return templateID;
// or property CODE
else if (prop.hasOwnProperty('CODE')) return templateCODE;
}
});
I'm doing a small crud operation. I want to capture more than one image from the video. I am using a fixedDialog while doing this. But after taking a picture, I can't see the video while opening the fixedDialog again. I share my codes below.
First time opening video,
After capturing,
<Button text="Resim Ekle" width="100px" id="idCapture" press="takePhoto"/>
<Vbox id="wow">
<Vbox id="canvasContainer">
</Vbox>
</Vbox>
takePhoto: function(oEvent) {
// Create a popup object as a global variable
var that = this;
that.fixedDialog = new Dialog({
title: "Fotoğraf çekmek için tıklayınız",
beginButton: new sap.m.Button({
text: "Resim Çek",
press: function() {
that.imageVal = document.getElementById("player");
that.fixedDialog.close();
}
}),
content: [
new sap.ui.core.HTML({
content: "<video id='player' autoplay/>"
}),
new sap.m.Input({
placeholder: 'Lütfen resim adını giriniz',
required: false
})
],
endButton: new sap.m.Button({
text: "İptal",
press: function() {
that.fixedDialog.close();
}
})
});
that.getView().addDependent(this.fixedDialog);
this.fixedDialog.open();
that.fixedDialog.attachBeforeClose(this.setImage, this);
var handleSuccess = function(stream) {
player.srcObject = stream;
};
navigator.mediaDevices.getUserMedia({
video: true
}).then(handleSuccess);
},
setImage: function() {
var oVBox = this.getView().byId("wow");
var canvasContainer = this.getView().byId("canvasContainer");
var items = oVBox.getItems();
var snapId = 'canvas-' + items.length;
var textId = snapId + '-text';
var imageVal = this.imageVal;
var snapImg = null;
var snapCanvas = new sap.ui.core.HTML({
content: "<canvas display:none id='" + snapId + "' width='400' height='200' ></canvas>"
});
oVBox.addItem(snapCanvas);
snapCanvas.addEventDelegate({
onAfterRendering: function() {
var canvasElem = document.getElementById(snapId);
var snapCanvasContext = canvasElem.getContext('2d');
snapCanvasContext.drawImage(imageVal, 0, 0, canvasElem.width, canvasElem.height);
}
});
}
I suggest you to check if your this.fixedDialog exists before performing a new Dialog(): I suspect you are adding more than one <video id='player' autoplay/> when you are opening the Dialog again...
I suggest you to add only
that.fixedDialog.destroy();
in press event
my code is below
takePhoto: function (oEvent) {
debugger;
// Create a popup object as a global variable
var that = this;
that.fixedDialog = new sap.m.Dialog({
title: "Open Camera For Video",
beginButton: new sap.m.Button({
text: "Capture",
press: function () {
that.imageVal = document.getElementById("player");
that.fixedDialog.close(this);
that.fixedDialog.destroy();
}
}),
content: [
new sap.ui.core.HTML({
content: "<video id='player' autoplay/>",
}),
new sap.m.Input({
placeholder: 'Name',
required: false
})
],
endButton: new sap.m.Button({
text: "Close",
press: function () {
that.fixedDialog.destroy();
that.fixedDialog.close();
}
})
});
that.getView().addDependent(this.fixedDialog);
this.fixedDialog.open();
that.fixedDialog.attachBeforeClose(this.setImage, this);
var handleSuccess = function (stream) {
player.srcObject = stream;
};
navigator.mediaDevices.getUserMedia({
video: true
}).then(handleSuccess);
},
setImage: function () {
var oVBox = this.getView().byId("wow");
var canvasContainer = this.getView().byId("canvasContainer");
var items = oVBox.getItems();
var snapId = 'canvas-' + items.length;
var textId = snapId + '-text';
var imageVal = this.imageVal;
var snapImg = null;
var snapCanvas = new sap.ui.core.HTML({
content: "<canvas display:none id='" + snapId + "' width='400' height='200' ></canvas>"
});
oVBox.addItem(snapCanvas);
snapCanvas.addEventDelegate({
onAfterRendering: function () {
var canvasElem = document.getElementById(snapId);
var snapCanvasContext = canvasElem.getContext('2d');
snapCanvasContext.drawImage(imageVal, 0, 0, canvasElem.width, canvasElem.height);
}
});
}
My problem is the following:
Linestring with two or more lines on the one or more coordinates.
With several LineStrings only one string is shown in the map, I know, the LineStrings also use the same coordinates.
Is there a way that the LineStrings can use one and the same coordinates, but a shift of the line (to have for example three lines next to each other) takes place in the structure of the map?
The code is a bit better, which explains a lot:
var logoElement = document.createElement ('a');
logoElement.href = 'http://www.schienenpost.de/';
logoElement.target = '_blank';
var logoImage = document.createElement ('img');
logoImage.src = 'http://www.schienenpost.de/schienenpost.png';
logoElement.appendChild (logoImage);
var iconStyle = new ol.style.Style ({
image: new ol.style.Icon (/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 1.0],
src: 'http://www.schienenpost.de/marker/marker.png'
}))
});
var scaleLineControl = new ol.control.ScaleLine();
var markerStartEnd = function (layer,feature) {
var i, iconFeature, iconFeatures = [], coordinates, nameLine;
coordinates = feature.getGeometry ().getCoordinates ();
nameLine = feature.getProperties () ['name'];
i = 0;
iconFeature = new ol.Feature ({
geometry: new ol.geom.Point (coordinates[i]),
name: 'Start'+nameLine,
});
iconFeature.setStyle (iconStyle);
iconFeatures.push (iconFeature);
i = coordinates.length - 1;
iconFeature = new ol.Feature ({
geometry: new ol.geom.Point (coordinates[i]),
name: 'End'+nameLine,
});
iconFeature.setStyle (iconStyle);
iconFeatures.push (iconFeature);
layer.getSource ().addFeatures (iconFeatures);
};
var layerLines = new ol.layer.Vector ({
source: new ol.source.Vector ({
format: new ol.format.GeoJSON (),
url: 'schienenpost.geojson',
useSpatialIndex: false
}),
style: new ol.style.Style ({stroke: new ol.style.Stroke ({color : 'red', width: 3})}),
});
var layerMarker = new ol.layer.Vector ({
title: 'Marker',
source: new ol.source.Vector ()
});
var element = document.getElementById ('popup');
var popup = new ol.Overlay ({
element: element,
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -0]
});
var map = new ol.Map ({
controls: ol.control.defaults ()
.extend ([
new ol.control.OverviewMap (),
new ol.control.FullScreen (),
scaleLineControl
]),
//target 'map',
target: document.getElementById ('map'),
layers: [
new ol.layer.Tile ({
source: new ol.source.OSM ()
}),
],
view: new ol.View ({
center: ol.proj.fromLonLat ([10.627, 53.620]),
zoom: 8
}),
logo: logoElement
});
map.addOverlay (popup);
map.addLayer (layerLines);
map.addLayer (layerMarker);
map.once ('moveend', function(e) {
layerLines.getSource ().getFeaturesCollection ().forEach (function (feature) {
markerStartEnd (layerMarker,feature);
});
});
map.on ('click', function (evt) {
var feature = map.forEachFeatureAtPixel (evt.pixel,
function (feature) {
return feature;
});
if (feature) {
var coordinates = feature.getGeometry ().getCoordinates ();
var clickpoint = map.getCoordinateFromPixel (evt.pixel);
if (!isNaN (coordinates [0])) { // Punkt
popup.setPosition (coordinates);
} else if (!isNaN (coordinates [0][0])) { // Linie
popup.setPosition (clickpoint);
} else { // kein brauchbares feature
$ (element).popover ('destroy');
return;
}
$ (element).popover ({
'placement': 'top',
'html': true,
'content': feature.get ('name')
});
$ (element).popover ().data ('bs.popover').options.content = feature.get ('name');
$ (element).popover ('show');
} else {
$ (element).popover ('hide');
}
});
map.on ('pointermove', function(e) {
if (e.dragging) {
$ (element).popover ('destroy');
return;
}
var pixel = map.getEventPixel (e.originalEvent);
var hit = map.hasFeatureAtPixel (pixel);
map.getTarget ().style.cursor = hit ? 'pointer' : '';
});
I've gone through the handy Famo.us University tutorials and am prototyping a drag & drop interface. It's the typical UI where the user can drag an icon and drop it onto a target to do something. I've gotten the drag part down, but detecting the drop is getting very hairy. Is there built-in collision detection in Famo.us?
Edit: I've looked at the Collision API but it's not clear whether this would work across views.
Here's how I've organized the project:
AppView (overall container)
|
|__ MenuView (sidebar) --> VizView (icons in MenuView)
|
|__ PageView (workspace where the drop targets live)
This may not be the best way to go about this. I'm not sure. Hooking up input events across the views seems to be painful.
VizView source:
/*** VizView.js ***/
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var ImageSurface = require('famous/surfaces/ImageSurface');
var Transitionable = require("famous/transitions/Transitionable");
var SnapTransition = require("famous/transitions/SnapTransition");
Transitionable.registerMethod("spring", SnapTransition);
var GenericSync = require('famous/inputs/GenericSync');
var MouseSync = require('famous/inputs/MouseSync');
var TouchSync = require('famous/inputs/TouchSync');
GenericSync.register({'mouse': MouseSync, 'touch': TouchSync});
function VizView() {
View.apply(this, arguments);
_createIcon.call(this);
}
VizView.prototype = Object.create(View.prototype);
VizView.prototype.constructor = VizView;
VizView.DEFAULT_OPTIONS = {
width: 200,
height: 100,
angle: -0.2,
iconSize: 98,
iconUrl: '',
title: 'Empty',
fontSize: 26
};
function _createIcon() {
this.zIndex = 0;
var me = this;
var iconSurface = new ImageSurface({
size: [this.options.iconSize, this.options.iconSize],
content : this.options.iconUrl,
properties: {
cursor: 'pointer'
}
});
var initModifier = new Modifier({
// places the icon in the proper location
transform: Transform.translate(24, 2, 0)
});
this.position = new Transitionable([0, 0]);
var positionModifier = new Modifier({
transform : function(){
var currentPosition = me.position.get();
return Transform.translate(currentPosition[0], currentPosition[1], me.zIndex);
},
});
var sync = new GenericSync(
['mouse', 'touch']
);
sync.on('start', function(data){
me.zIndex = 1;
});
sync.on('update', function(data){
me.updateIcon(data);
});
sync.on('end', function(data){
var velocity = data.velocity;
me.position.set([0, 0], {
method : 'spring',
period : 150,
velocity : velocity
});
me.zIndex = 0;
});
iconSurface.pipe(sync);
this.add(positionModifier).add(initModifier).add(iconSurface);
this.updateIcon = function (data) {
if (this.zIndex == 0) return;
var currentPosition = this.position.get();
this.position.set([
currentPosition[0] + data.delta[0],
currentPosition[1] + data.delta[1]
]);
}
}
module.exports = VizView;
});
A VizView is instantiated in MenuView as such:
var vizView = new VizView({
iconUrl: "path/to/iconUrl",
title: "Viz Title"
});
var vizModifier = new StateModifier({
transform: Transform.translate(0, yOffset, 0)
});
this.add(vizModifier).add(vizView);
A draggable Surface in Famo.us is not really a DOM draggable element although it can be setup to work in a browser using the mouse. I have not been able to get GenericSync and touch to work with this solution yet.
Reading the pitfalls on the Famo.us site, there are hints to drag and drop with surface draggables being an issue.
How do I find the absolute position of a Surface on the screen?
By design this is not possible. It is something the developer should
not care about. For the time being, this means that interactions such
as drag and drop are harder to implement, but this is intended and we
are working on an elegant solution for these use-cases.
Although: When not using GenericSync, you can use the DOM draggable events with a Famo.us Surface as you stated in the comments and link to the John Traver solution.
But: This solution will not work on mobile touch devices using Famo.us at the time of this answer. Getting this to work with touch may prove to be more difficult as stated in the pitfalls. Let's hope this gets solved in versions following 0.3.5 or in MixedMode (WebGL and DOM)
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var ImageSurface = require('famous/surfaces/ImageSurface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var mainContext = Engine.createContext();
var transTransform = new TransitionableTransform();
transTransform.set(Transform.translate(100, 0, 0));
var captureSurface = new Surface({
content: 'Drag to Here',
size: [300, 300],
properties: {
textAlign: 'center',
lineHeight: '300px',
backgroundColor: 'rgba(255,255,0,0.4)',
cursor: 'pointer'
},
attributes: {
dropzone: 'copy file:image/png file:image/gif file:image/jpeg'
}
});
captureSurface.on('dragenter', function(evt) {
console.log('dragenter', evt);
evt.preventDefault();
return false;
});
captureSurface.on('dragleave', function(evt) {
console.log('dragleave', evt);
captureSurface.setProperties({
border: 'none'
});
evt.preventDefault();
return false;
});
captureSurface.on('dragover', function(evt) {
console.log('dragover', evt);
captureSurface.setProperties({
border: '4px dashed black'
});
evt.preventDefault();
return false;
});
captureSurface.on('drop', function(evt) {
console.log('drop', evt);
evt.preventDefault();
evt.stopPropagation();
captureSurface.setProperties({
border: '4px solid red'
});
files = evt.dataTransfer.files;
console.log(files);
});
mainContext.add(new Modifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
})).add(captureSurface);
var surface = new Surface({
content: 'DOM Draggable',
size: [300, 100],
properties: {
backgroundColor: 'rgba(255,0,0,0.4)',
cursor: 'move'
},
attributes: {
draggable: 'true'
}
});
surface.on('drag', function(evt) {
console.log('surface drag', evt)
});
var imageSurface = new ImageSurface({
content: 'http://i.imgur.com/NGOwZeT.png',
size: [100, 100],
properties: {
cursor: 'copy'
},
attributes: {
draggable: 'true'
}
});
imageSurface.on('drag', function(evt) {
console.log('imageSurface drag', evt)
});
imageSurface.on('dragend', function(evt) {
console.log('imageSurface dragend', evt)
});
var dragSurface = new Surface({
content: 'Drag Me',
size: [100, 100],
properties: {
backgroundColor: 'rgba(0,0,0,0.1)',
cursor: 'move'
},
attributes: {
draggable: 'true'
}
});
dragSurface.on('dragstart', function(evt) {
console.log('dragSurface dragstart', event, evt);
});
dragSurface.on('drag', function(evt) {
console.log('dragSurface dragstart', event, evt);
});
var modifier = new Modifier({
origin: [0, 0],
align: [0, 0],
transform: transTransform
});
var imageModifier = new Modifier({
origin: [0, 0.5],
align: [0, 0.5]
});
var draggable = new Draggable();
draggable.subscribe(dragSurface);
mainContext.add(modifier).add(surface);
mainContext.add(imageModifier).add(imageSurface);
mainContext.add(draggable).add(dragSurface);
draggable.on('update', function(e) {
console.log('draggable update', e, event);
var pos = e.position;
surface.setContent('Draggable Position is ' + pos);
transTransform.set(Transform.translate(pos[0] + 100, pos[1], 0));
});
draggable.on('end', function(e) {
var pos = e.position;
surface.setContent('Draggable End Position is ' + pos);
transTransform.set(Transform.translate(pos[0] + 100, pos[1], 0));
});
//draggable.deactivate();
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
I have error about for info window data. I can't get the Please help me to check my code.
function initialize() {
map = new google.maps.Map(document.getElementById(map), {
center: new google.maps.LatLng(1.352083, 103.819836),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//var infowindow;
if (markers) {
for (var level in markers) {
for (var i = 0; i < markers[level].length; i++) {
var details = markers[level][i];
//var infowindow;
markers[level][i] = new google.maps.Marker({
title: details.name,
position: new google.maps.LatLng(
details.location[0], details.location[1]),
clickable: true,
draggable: false,
icon: details.icon
});
var infowindow = new google.maps.InfoWindow({
content: details.description,
//content : markers[level][i].description,
position: new google.maps.LatLng(details.location[0], details.location[1])
//position: markers[level][i].position
});
google.maps.event.addListener(markers[level][i], 'click', function() {
infowindow.setPosition(this.position);
alert(this.position);
//infowindow.setContent(markers[level][i].description);
infowindow.open(map,markers[level][i]);
});
}
}
}
I can't get the description data. Please help me to check my code.