Open Layers Features move when zooming out - javascript

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.

Related

Polygon drawing upon map tiles where a custom tile server is used using Openlayers 3

Has anyone tried drawing a polygon in an area where local server tiles are used in Openlayers3?
For a specific area on the map I am using local server tiles to visualize a building's plan while for the rest stamen tiles are used.
The issue is that once the polygon is drawn it "gets lost - disapears" under the tiles probably. If I try to draw a polygon on the area "outside" the one that custom tiles are rendered everything is ok.
I played a bit with the zIndex in the custom tiles but no luck. Any ideas?
I was trying to set the zIndex on both local tiles (to be lower than the drawn feature) and the drawn feature to be bigger than the local tiles but in the end as the drawn feature gets inserted into a Vector Layer I added a vector Layer on the map, set the zIndex there and once the polygon was drawn removed it using clear().
Thus,
Construct the vector Layer
var stamenTiles = new ol.layer.Tile({
source: new ol.source.Stamen({
layer: 'toner'
})
});
var source = new ol.source.Vector(); //DRAWING
var vector = new ol.layer.Vector({ //DRAWING
source: source,
zIndex: 100 // place the Polygon on top of the local tiles
});
Map object:
var map = new ol.Map({
target: 'map',
layers: [stamenTiles, vector],
view: new ol.View({
center: ol.proj.fromLonLat([CoordinatesFactory.getLongitude(), CoordinatesFactory.getLatitude()]),
zoom: 19,
minZoom: 19,
maxZoom: 22
})
});
Remove drawn vector layer
vector.getSource().clear();

OpenLayers 4, whenever you zoom with mousewheel fast the map dissapears

I have a map done with OpenLayers 4.3.2 with a lot of layers, sometimes 10, but only one shows at a time. The initialization of the map object is done like this:
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: ol.coordinate.createStringXY(4),
projection: 'EPSG:4326',
className: 'ol-lat-lon',
target: getElementById('location'),
undefinedHTML: ' '
});
//This is the control for the scale line at the bottom of t
var scaleLineControl = new ol.control.ScaleLine();
ol3view = new ol.View({
projection: _map_projection,
center: defCenter,
zoom: mapConfig.zoom,
maxZoom: mapConfig.zoomLevels,
zoomFactor: mapConfig.zoomFactor,
maxResolution: mapConfig.maxResolution
extent: resExtent // Not working
});
map = new ol.Map({
interactions: ol.interaction.defaults({mouseWheelZoom:false})
.extend([
new ol.interaction.MouseWheelZoom({
constrainResolution: true,
duration: 250, timeout: 200
})
]),
controls: ol.control.defaults()
.extend([mousePositionControl, scaleLineControl]),
overlays: [ol_popup], //Overlay used for popup
target: 'map', // Define 'div' that contains the map
renderer: 'canvas',
view: ol3view
});
What happens is that whenever i make a zoom with the mousewheel kinda fast the map disappears, it breaks.
The MouseWheelZoom interaction defined is an attempt to see if changing the times of the animation or Mouse wheel timeout of the zoom would stop breaking the map.
This bug occurs specially with Tiled layers that have streamlines but can be replicated with any layer.
I used to have this same web app done with OpenLayers 3 and this bug never ever happened, so it has definitely something to do with the new OpenLayers version, but I can't find a fix for it. Here is a link to the app I'm currently testing on, where you can replicate the bug: http://pronosticos.unam.mx:8080/MASTEROL4/mapviewer

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.

Displaying Static Images at 100% in OpenLayers

I would like to display static images as maps using a StaticImage layer in ol3, at 100% of the image size in pixels. I believe this should be defined by the extent and zoom variables, but the displayed images are not always the correct size, depending on the image, so I am clearly misunderstanding something, in spite of all of the forum entries I have read.
Here is a fiddle demonstrating incorrect image sizes. The reference image is 128x128 pix, but the displayed image is slightly larger at zoom 0.
The provided example from OpenLayers works just fine if used in my fiddle, and we seem to learn that if the extent variable is [0,0,wid,len], then zoom: 2 is 100%. But this does not hold with all images.
How can static images be reliably displayed at 100% of their size in pixels?
Thanks in advance for your help.
var extent = [0,0,128,128] // image size is 128x128 px
var projection = new ol.proj.Projection({
code: 'local_image',
units: 'pixels',
extent: extent
});
var map = new ol.Map({
target: 'map',
view: new ol.View({
projection: projection,
center: ol.extent.getCenter(extent),
zoom: 0,
}),
controls: [],
});
var im_layer = new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'http://img4.wikia.nocookie.net/__cb20071014061100/freeciv/images/1/1c/Crystal_128_penguin.png', // image size is 128x128 px
projection: projection,
imageExtent: extent
})
})
map.addLayer(im_layer)
I finally found an answer to this problem. Instead of using the "zoom" variable in the map view, use the "resolution" parameters instead.
Setting the following, in addition to the above, results in an image displayed at 100%:
var map = new ol.Map({
view: new ol.View({
resolution: 1, // important for 100% image size!
maxResolution: 2, // must be >= 1
//minResolution: .5, // also set-able
//zoom: 0, // don't use this
...
})
...
})
Here is an updated fiddle.

Open layers features

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.

Categories