How to display WFS in OpenLayers 6? - geoserver

i trying to display vector layer as WFS from local GeoServer in OpenLayers 6.3.1. When i trying add new vector layer, at the map i see only base map. However all data at GeoServer has projection EPSG:3857.
How to fix this problem?
My code:
var vectorSource = new VectorSource({
format: new GeoJSON(),
url: function(extent) {
return 'http://localhost:8080/geoserver/geodata/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=geodata%3Amlink&maxFeatures=50&outputFormat=application%2Fjson';
},
strategy: bboxStrategy,
});
var vector = new VectorLayer({
source: vectorSource
});
var map = new Map({
layers: [
new TileLayer({
source: new OSM(), //projection: 'EPSG:3857',
opacity: 0.7
}),
vector],
target: document.getElementById('map'),
view: new View({
//projection: 'EPSG:3857',
center: [6181942.5743,7443423.3883],
zoom: 11
//maxZoom: 19,
//zoom: 12
})
});

Related

A-Frame: Geometry Caching / Registering new Geometry from GLTF

I'm hoping to get some help using geometry instancing with A-Frame. I was trying to figure out the bottleneck for my web app and after implementing pooling for physics objects being created in the scene, saw that the number of draw calls was increasing with each new object -- I had thought that by utilizing the asset management system in A-Frame my models were automatically cached, but I think I was mistaken.
I was wondering, if I register the geometry of the model using AFRAME.registerGeometry, would I be able to utilize geometry instancing? I saw that creating from a pool of object using the A-Frame geometry primitives did not increase the geometry count of the scene on a per-entity basis. I took a shot at loading my GLTF and registering the geometry from the mesh, but I'm getting an error from a-node that I don't understand:
<script>
AFRAME.registerGeometry('ramshorn', {
schema: {
depth: {default: 1, min: 0},
height: {default: 1, min: 0},
width: {default: 1, min: 0},
},
init: function(data) {
var model = null;
var geometry = null;
var manager = new THREE.LoadingManager();
manager.onLoad = function () {
console.log(geometry);
this.geometry = geometry;
console.log(this.geometry);
}
var gltfLoader = new THREE.GLTFLoader(manager);
gltfLoader.setCrossOrigin('anonymous');
const src = "./assets/ramsHorn/Ram's Horn 2.gltf";
gltfLoader.load(src, function ( gltf ) {
console.log("Gltf: " + gltf);
model = gltf.scene;
console.log("Model: " + model)
model.children.forEach((child) => {
console.log(child);
});
gltf.scene.traverse(function (o) {
if (o.isMesh) {
geometry = o.geometry;
//console.log(geometry);
//tried assigning "this.geometry" here
}
});
}, undefined, function ( error ) {
console.error(error);
});
//tried assigning "this.geometry" here
}
});
</script>
Error:
core:a-node:error Failure loading node: TypeError: "t is undefined"
aframe-master.min.js:19:658
Any help with this would be appreciated! Thanks
The code at 19:658 in aframe-master.min.js is trying to run something with a variable t but it has not been declared.
By using aframe-master.js it would be possible to get a more meaningful error.

how to Optimize response speed or performance of GeoWebcache from Openlayer Request

I have TileLayer that contains a bunch of data on GeoServer2.13 and making the request from browser client using OpenLayers v4.1 API.
what all done is:
1.Openlayer Map with projection:
var map: any = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'Map',
projection: 'EPSG:900913',
controls: ol.control.defaults({
attributionOptions: {
collapsible: false
}
}),
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
2.WMS Request as tiled True:
layer: new ol.layer.Tile({
source: new ol.source.TileWMS({
url: _GESERVER_URL +'geo/wms',
params: {
'FORMAT': 'image/png',
'VERSION': '1.1.1',
'TILED': true,
'LAYERS': 'geo':myTileLayer'
},
projection: 'EPSG:4326'
})
})
3.On GeoServer:
-Layer Data tab SRS:4326
-Http Setting response header 3600
-Seeding Executing task 1
-ZoomLevel 15
-GridSet:EPSG:900913 and EPSG:4326
-Metatiling factors 4 by 4
-Image Format image/jpeg and image/png
-DiskQuata:3GB
-TileDimensions:256 x 256
I also tried with image/png8 but still speed up is not at all working.
Any other configuration required to make GeoWebcache with more performance?
You are requesting the tiles in a different projection than your map is displayed in, which forces OpenLayers to reproject the tiles. This takes time and reduces quality.
Remove the line projection: 'EPSG:4326' from your WMS layer.
Also to be sure you are hitting your tile cache please use a tiled endpoint such as WMTS rather than hoping your tiles end up hitting the cache (unlikely since you don't specify an origin in your WMS). See the OpenLayers WMTS example for details.
var parser = new ol.format.WMTSCapabilities();
var map;
fetch('https://openlayers.org/en/v4.6.5/examples/data/WMTSCapabilities.xml').then(function(response) {
return response.text();
}).then(function(text) {
var result = parser.read(text);
var options = ol.source.WMTS.optionsFromCapabilities(result, {
layer: 'layer-7328',
matrixSet: 'EPSG:3857'
});
map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
opacity: 0.7
}),
new ol.layer.Tile({
opacity: 1,
source: new ol.source.WMTS(/** #type {!olx.source.WMTSOptions} */ (options))
})
],
target: 'map',
view: new ol.View({
center: [19412406.33, -5050500.21],
zoom: 5
})
});
});

Is it possible to have a white basemap using d3.js and leaflet?

I'm visualizing data on top of a world map using d3 and leaflet. I would like the base map layer to be white, like the one in the following link.
https://resistancemap.cddep.org/AntibioticUse.php
CartoDB doesn't support white base layers though. The one I'm using is positron. Is there some way to make that grey area become white with d3 and leaflet?
This is the code for adding the layers..
var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors, © CartoDB'
});
var map1 = L.map('map1', {
center: [19.711510, -4.935242],
zoom: 2,
layers: [positron]
});
var baseLayers = {
"Grayscale (CartoDB)": positron
};
var d3Layer = L.Class.extend({
initialize: function() {
return;
},
onAdd: function() {
d3.select("div#map1 .legend").style("display", "block");
d3.select("div#map1 .regions").style("display", "block");
},
onRemove: function() {
d3.select("div#map1 .regions").style("display", "none");
d3.select("div#map1 .legend").style("display", "none");
},
});
var svgLayer = new d3Layer();
var overlays = {
"GeoJSON Regions": svgLayer
};
L.control.layers(baseLayers, overlays).addTo(map1);
Thanks!
Simply don't add any L.TileLayers to your map, and use CSS to set its background.
If you're open to try, you can use mapbox-gl.js library, which allows to use personalized vector tiles as basemap, so you can customize any element of the basemap. Here you can find some guidelines. Then, it's as easy as passing a property to the map definition:
//Mapbox API Token
mapboxgl.accessToken = '{API TOKEN}'
//Setup mapbox-gl map
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/{USERNAME}/{STYLE_ID}', //Copied from Mapbox Studio
center: [Lng, Lat],
zoom: 4,
})
Additionaly, you can use D3.js to work with your data layers, as shown in this example, you just need to include the update() and projectPoint(lon, lat) functions after loading data into SVG elements.
I recently managed to configure the vector tiles and it's awesome how smooth they run with pan/zoom/rotation.

How to select all features in cluster layer in openlayers 3

I've got a simple code and a simple map with adding features and clustering them all together. Straight from example:
var vectorSource = new ol.source.Vector({
projection: 'EPSG:4326'
});
var clusterSource = new ol.source.Cluster({
distance: 30,
source: vectorSource
});
var styleCache = {};
var clusters = new ol.layer.Vector({
source: clusterSource,
style: function(feature, resolution) {
var size = feature.get('features').length;
var style = styleCache[size];
var src;
if (!style) {
if( size == 1 ){
src = 'images/location-single.png';
}else{
src = 'images/location-multi.png';
}
style = [
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: '#5bc0de'
})
})
}),
new ol.style.Style({
image: new ol.style.Icon(({
// scale: 1 + rnd,
// rotateWithView: (rnd < 0.9) ? true : false,
// rotation: 360 * rnd * Math.PI / 180,
anchor: [0.45, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
// opacity: rnd,
src: src
})),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#000'
})
})
})
];
styleCache[size] = style;
}
return style;
}
});
var map = new ol.Map({
target: 'map', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
layers: [
// Add a new Tile layer getting tiles from OpenStreetMap source
new ol.layer.Tile({
source: new ol.source.OSM()
}),
clusters
],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 6
})
});
Now i got cluster function working fine. But i need to show coordinates for every point in the cluster, i've tryed to use map.forEachFeatureAtPixel, but it doesent work for ALL the features in the cluster. How do i select them all?
Oh. I think i got it! A cluster is a feature and got its properties. so we can GET all features in a cluster by using .getProperties()
as in:
map.on('singleclick', function(event) {
map.forEachFeatureAtPixel(event.pixel, function(feature) {
var featuresInCluster = feature.getProperties().features;
});
});
But i would really like to know if is there another way?
/***First create a select interaction object by assigning the cluster layer you created**/
var select = new ol.interaction.Select({
layers: [clusters]
});
/**Then add the created select object**/
map.addInteraction(select);
var selectedFeatures = select.getFeatures();
/**Then write this code**/
selectedFeatures.on('add', function (event) {
// event.target only contains the clustered point
var feature = event.target.item(0);
console.log(feature)
});
/***HOPE IT WILL WORK**//

Rotating around origin - Famo.us

How can I rotate ImageSurface around it's origin if I have applied translate to it ?
It does not rotate around origin. Can someone explain me is it using "align point" as center of rotation ?
EDIT
My ImageSurface is rotating like it has distante point of rotation and it scales up.
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
this.fbLogo.on("mouseleave", function(){
fbModifier.setTransform(Transform.rotateZ(Math.PI/4), { duration: 1000});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(this.fbLogo);
}
MY SOLUTION
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
var fbRotateModifier = new Modifier();
var transitionable = new Transitionable(0);
this.fbLogo.on("mouseleave", function(){
transitionable.reset(0);
fbRotateModifier.transformFrom(function(){
return Transform.rotateZ(transitionable.get());
}
);
transitionable.set(2 * Math.PI, {curve: "inOutQuad", duration: 500});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(fbRotateModifier).add(this.fbLogo);
}
This can be done using straight Famo.us, no need to modify CSS. Here's an example. Some of these modifiers can be combined, but I'm breaking them up for clarity. Centering the origin is first applied to a Surface. Rotations now pivot about the newly defined origin. Then the rotated Surface is translated.
var surface = new Surface({
size : [100,100],
properties : {background : 'red'}
});
var translateModifier = new Modifier({
transform : Transform.translate(100,0,0)
});
//rotates around and around based on your current system time
var rotateModifier = new Modifier({
transform : function(){ return Transform.rotateZ(Date.now() * .001) }
});
var centerModifier = new Modifier({
origin : [.5,.5]
});
context
.add(translateModifier)
.add(rotateModifier)
.add(centerModifier)
.add(surface)
I had similar problems to spin an element. The transform origin needs to be set center (50% 50%). I used css class for this.
.myClass {
-webkit-transform-origin: 50% 50% !important;
}
var myElem = new Surface({
size: [40, 40],
classes: ['myClass']
});
this.myElemModifier = new StateModifier();
// called from user action
this.myElemModifier.setTransform(
Transform.rotateZ(Math.PI), { duration: 5000 }
);

Resources