Open layers features - javascript

Why cant I add feature to Vector? This code is not working:
var features = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-70.702451, 42.374473), {className: "latarnia"})]
vectors = new OpenLayers.Layer.Vector("warstwa", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
format: new OpenLayers.Format.OSM()
}),
features : features,
projection: new OpenLayers.Projection("EPSG:4326")});
map.addLayers([vectors]);
I mean vectors has no features at all.
I tried
layer.addFeatures([feature]);
but it fails as well.

it seems that the projection of your map and point is not the same.
map peojection is EPSG:4326 , but it seems that point projection is EPSG:3857.
it may help you
conv_latlon = new OpenLayers.LonLat(-70.702451, 42.374473).transform('EPSG:3857', 'EPSG:4326')//transform point
var features = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(conv_latlon.lon, conv_latlon.lat), {className: "latarnia"})]

For some reason initializing "features" property on OpenLayers.Layer.Vector constructor does not work.
But you should be able to add them afterwards:
vectors.addFeatures(features);
You can then test in browser console:
vectors.features.length; //this should be 1 now
Otherwise the code seems ok.
You should also be able to see the feature on map as an orange circle (default style), but only if the point's coordinates are inside the extent of your base layer.
Tested with OpenLayers version 2.14.

Related

openlayers 6 map getview fit zooms out on every refresh

Im using openlayers 6, on mounted I use map().getView().fit(extent)
for some reason on every refresh the zoom level is higher.
any tips how to fix this?
Before using .fit(extent) I have to transformExtent to change projection from 5514 to 3857
this.map().setView(new View({
projection: 'EPSG:3857',
center: fromLonLat([50.075710, 14.472606]),
zoom: 10,
enableRotation: false
}))
extent = transformExtent(extent, 'EPSG:5514', this.map().getView().getProjection().getCode())
this.map().getView().fit(extent)
before refresh:
after refresh:
my problem is with map.getview.fit
here is my code and here are the returned values
coordinates after view.fit are a bit different
console.log(transformedExtent)
this.map().getView().fit(transformedExtent, this.map().getSize())
console.log(this.map().getView().calculateExtent(this.map().getSize()))
before fit:
-27186.072153485078
6701982.491006854
-5136.804165771885
6724373.669054876
after fit:
-27186.072153485078
6701493.775314425
-5136.804165771886
6724862.384747305
Asked about this problem directly on openlayers github and it is expected behavior.
https://github.com/openlayers/openlayers/issues/13503
You are using the same variable for the EPSG:5514 and EPSG:3857 extents so presumably corrupting the original EPSG:5514 you want to use. Using a separate variable should solve the problem.
const transformedExtent = transformExtent(extent, 'EPSG:5514', this.map().getView().getProjection().getCode())
this.map().getView().fit(transformedExtent)

Open Layers Features move when zooming out

EDIT: I changed the center of the map by user-input before but changed this for testing. Using a fixed center for my map, everything is fine. Question now is: why?
I am looping through a JSON with some features, extracting the coordinates for each feature, and add them to a map.
So far everything is working fine, but I just noticed that the features or better the icons are moving when I am zooming out/in or moe left/right.
The feature location should still be true since I am able to hover over the map and show an overlay (as intended).
I have no idea why the logos would behave like this, maybe someone can help me. Here is my code for one of the layers:
///////////////
// Forst
var Forststyle = new ol.style.Style({
image: new ol.style.Icon({
src: 'images/tree.png'
})
});
var Forstsource = new ol.source.Vector();
$.getJSON('config/Forst.json', function (data) {
$.each(data, function(key, val){
var newMarker = new ol.Feature({
geometry: new ol.geom.Point([this.long, this.lat]),
pointAttributes: {
'Name': this.name,
'Strasse':this.Straße,
}
});
Forstsource.addFeature(newMarker);
});
});
var Forst = new ol.layer.Vector({
title: "Forst",
visible: false,
zIndex: 5,
style: Forststyle,
source: Forstsource});
I am adding the Forst-Layer to the layers of my map.
I thought my projection/view definition might be helpful.
var projection25832 = new ol.proj.Projection({
code: 'EPSG:25832',
// The extent is used to determine zoom level 0. Recommended values for a
// projection's validity extent can be found at https://epsg.io/.
extent: [-1877994.66, 3932281.56, 836715.13, 9440581.95],
units: 'm'
});
I am adding my whole map-call. center and zoom get defined by user-input.
var map = new ol.Map({
target: 'map',
layers:[
new ol.layer.Tile({
title: 'OSM (grau)',
visible: true,
source: new ol.source.TileWMS({
url: 'https://ows.terrestris.de/osm/service?',
params: {
'LAYERS': "OSM-WMS",
'VERSION': '1.1.0',
'FORMAT': 'image/png',
'TILED': false
}
})
}),
Schaefer,
KMR,
GaLaBauSA,
GaLaBauBBG,
Forst,
Lohnunternehmen
],
view: new ol.View({
projection: projection25832,
center: center,
zoom: zoom
})
});
I am adding some images, view1 and view2 are only changed by scrolling left/right, view3 is zoomed in.
Some more edits:
As stated above, when I am using a fixed center everything is working as intended. However, changing it depending on User Input is not working.
var D = $.ajax({
type: "GET",
url: url,
dataType: "json"
}).done(function(){
var Coords = D.responseJSON.results[0].locations[0].latLng;
var utm = "+proj=utm +zone=32";
var new_center = [proj4("WGS84",utm,[Coords.lng, Coords.lat])[0],proj4("WGS84",utm,[Coords.lng, Coords.lat])[1]];
console.log(new_center);
CreateMap([new_center[0], new_center[1]],zoom);
$("#Hintergrund").hide();
});
}
My CreateMap function is taking the coordinates of the center and the zoom, the url is a WEB-API (mapquest) that turns input into coordinates. If I pass e.g. my home-zip-code I get the coordinates that are used as my fixed center in the log, so there should not be a problem with the coordinates right?
Your image moving on zoom, because it automatically scales so the size would be readable regarding the zoom level (It doesn't stick to the map) You would need to anchor the center of the image elsewhere.
To anchor the center image you must play around with offsets.
You can, play with offsets and image size itself with openlayers style class. I dont know which version you are using, so you most likely will have to read about it in the documentation or some other examples, but hare is one.
new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0, 0],
anchorXUnits: "pixels",
anchorYUnits: "pixels",
offset: [0,0],
offsetOrigin: 'bottom-left',
rotation: 0,
src: 'images/tree.png'
}))
});
Setting anchor to 0,0 will be top left if Im not mistaken, you most likely will have to set it to 0, {Half width}
Basically, when you scroll and zoom, OpenLayers adjusts your image scaling from its center point, so in theory it will move if the center point isnt for example at the bottom.
If that doesn't help, see if you have correct projections.
And if that doesn't help, try creating "Markers" instead of points, I don't recall but one of them has way more control flow going.
I imagined it moved by tiny bit, seems like it drastically moves. Might be projections fault. Try to use projection: 'EPSG:4326' if your coordinates are in different one, you can convert it with
.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"))
I noticed you create projection manualy, not sure if thats the best approach. Check out this one.
https://openlayers.org/en/latest/examples/epsg-4326.html
Its using 4326. It is always better to use openlayers projection and if you have coordinates built differently, transform them to your needed ones.
To debug this, you can try to draw a linestring on a map (WKT/Polyline) if that changes on zoom, your problem is definitely in projections, if not, then it might be something else.
I was working with openlayers recently as well. And ran into the same problem, which I made by add
style.graphicXOffset= 15;
style.graphicYOffset= 28;
Set these to 0, should help.

How to apply a custom local/offline map style to an OpenLayers Map

I have a local webpage as part of a larger desktop application. I want to change the default style of the Open Layer map to "Klokantech Basic". I've downloaded a copy of the style JSON but struggeerling to apply it to the map. Currently my code looks like:
var map = new ol.Map({
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],
target: 'map',
style: './mapStyle.json',
view: new ol.View({
center: ol.proj.fromLonLat([-0.146953, 51.493758]),
zoom: 15
})
But setting a style isn't working, I've looked online and there appears to be Map Box, this however uses an API key, something which I don't want to use/ maintain.
The whole page and its resources are stored locally, is there any way of referencing the local style file without an API?
Here is my current code.
The mapbox style is for vector tile source and I pretend you use it for your vector layer.
Openlayers don't seem to support the Mapbox style for MVT. It use a style function to apply to the vector tile.You can see here a exemple of how Openlayers make style function for vector tiles.

Finding vector source features in extent with wrapX

I currently have features on an ol.source.Vector that I would like to find by drawing a box (MultiPolygon) on the screen. I currently have this functionality working, however, if I move onto the next rendered world ("spin the globe" so to speak) when I draw my box over the same set of rendered features I get nothing back.
Example code:
var featureSource = new ol.source.Vector({
url: '/ShinyService/feature/geoJson',
format: new ol.format.GeoJSON()
});
var featureLayer = new ol.layer.Vector( {
source: featureSource
});
var myMap = new ol.Map({
layers: [ featureLayer],
view: new ol.View({
minZoom: 3,
maxZoom: 10
});
});
//Later within interaction event (draw end)
var boxExtent = box.getGeometry().getExtent();
vectorSource.forEachFeatureInExtent(boxExtent, function(feature){
foundFeature.push(feature.getId());
});
I'm currently thinking the only "solution" to this is to no longer allow the world to be rendered multiple times, but I don't think this is an option for the requirement I'm trying to fulfill.
I'm currently using Openlayers v3.18.2
Any help would be appreciated!
I was able to figure my problem out. It turned out I had to "wrap" the coordinates of my extent in order to get it to work properly as they were going past the -180 to 180 boundary. Once I did this every thing seemed to work.
However, this feels like something that should already be done in Openlayers so there could be something else I could be missing.

Openlayers initial extent

According to the OpenLayers documentation, the constructor, OpenLayers.Map(), allows for an additional property extent which is "The initial extent of the map" (see here).
However, I cannot get it to have any effect. I know I can set an initial extent by calling .zoomToExtent() after constructing the map. But I would like to use this extent property because I set a zoomend event in the eventListeners property but don't want it to trigger with an initial call to .zoomToExtent(). Does anyone have a clue how to use this extent property?
This is the code that isn't working
map = new OpenLayers.Map('map',{
extent: bounds,
layers: [osmLayer,vectorLayer],
projection: "EPSG:900913",
eventListeners: {
zoomend: function() {
//..zoomend event listener code
}
}
});
In the above example:
bounds is a valid OpenLayers.Bounds object
osmLayer and vectorLayer are valid OpenLayers.Layer objects of which osmLayer is the base layer.
What happens with above code is that the map is completely zoomed out (in fact you can't actually see anything) and any attempts to pan results in errors being thrown. To get to map into a correct state the user has to zoom in and then panning works again and you can see the map.
I'm afraid I'm not sure off-handedly how to make the code you listed work, however the following alternative has worked for me:
map = new OpenLayers.Map('map',{projection: new OpenLayers.Projection("EPSG:4326")});
//ADD A BUNCH OF LAYERS AND SUCH HERE
//Set map center to this location at this zoom level
map.setCenter(new OpenLayers.LonLat(-93.9196,45.7326),5);
As a last resort, you could put a line at the beginning of your zoom function:
if(!map_ready) return;
And then set the variable map_ready to true at the appropriate time.
I ran into the same problem.
The "extent" option mentioned in the documentation is there probably by mistake. It does not exist. I checked the source code and could not see any code handling such option. I contacted the author and he already created a pull request for the removal of this option from the documentation.

Categories