Open layer check if feature is in viewport - javascript

My purpose is to display only features that have coordinate inside my map viewport (map area currently displayed).
I get the extent of the viewport by doing:
var mapExtent = this.map.getView().calculateExtent(this.map.getSize());
mapExtent = ol.proj.transformExtent(mapExtent, 'EPSG:3857', 'EPSG:4326');
and after, in a loop where I am reading the element of one store,
var point = ol.proj.fromLonLat([
element.get('longitude'),
element.get('latitude')
]);
elementPoint = new ol.geom.Point(point);
var feature = new ol.Feature(elementPoint);
var coordsFeatures = feature.getGeometry().getCoordinates();
and after, just to quickly see if the point is inside my viewport, I use just a console log:
console.log(ol.extent.containsXY(mapExtent, coordsFeatures[0],coordsFeatures[1]));
/*if(!ol.extent.containsXY(mapExtent, coordsFeatures[0],coordsFeatures[1])){
return true;
}*/
But I don't know why, the result is only false, even if for sure there are points inside the map area currently displayed.
Whart I am doing wrong?

You are mixing projections.
For the extent, you change from 3857 to 4326.
For the point, by applying ol.proj.fromLonLat(), you change from 4326 to 3857 (the default)
Just use 3857 or 4326 for both

So I will post the correct code in case someone else may need it. As mentioned by #GH (thank you again) my problem was the mixing projections, so I changed my code in this way:
instead of using the coordinate, I get the extent of the feature:
var extentFeature = feature.getGeometry().getExtent();
and after i applied to it the same transformExtent used for the map:
extentFeature = ol.proj.transformExtent(extentFeature, 'EPSG:3857', 'EPSG:4326');
if(!ol.extent.containsExtent(mapExtent, extentFeature)){
return true;
}
and now it works! :D

Related

OpenLayers : 4326 ol.proj.transform not working

Issue
When I click on the map I want to transform the coordinates to format of 4326. When I do this it seems the Latitude part of the array transforms fine, but the Longitude part is incorrect and not valid.
Code
When I click on the Map, the SingleClick event fires, I then get the coordinates of where the user clicked:
Example of pPointClicked = [-40364190.03366159, 7054830.416117247];
session.Map.on('singleclick', function (e) {
var pPointClicked = e.coordinate;
});
I try and transform these coordinates into 4326 by using the code below:
Example of coord4326 = [-362.59768838343064, 53.38659640004323];
session.Map.on('singleclick', function (e) {
var pPointClicked = e.coordinate;
var coord4326 = ol.proj.transform(pPointClicked, 'EPSG:3857', 'EPSG:4326');
});
As you can see the first value in the transformed variable is -362.59768838343064 which is incorrect? Does anyone know why this is happening.
The transformation seems to be working. Here's what I think is happening: you are not within the "original extent" of your map, i.e. you panned west and wrapped the entire world at least twice.
Try zooming out completely, then pan at the "same" location to the east twice, then click again. You should have the coordinate you're looking for.
Here's an other tip: the world extent, in EPSG:3857, is:
[
-20037508.342789244,
-20037508.342789244,
20037508.342789244,
20037508.342789244
]
[-40364190.03366159, 7054830.416117247] is out of that extent, but if you pan to wrap the world twice, you should get: 289173.348083102, 7054830.416117247], which is within the extent.

OpenLayers Point Geometry never resizes

My website contains an OpenStreetMaps. I use OpenLayers to place a Geometry.Point on top of a city.
A button allows the user to resize this point, but it is never resized and I can't understand why.
Here is my code :
var button = document.myform.btClear,
map = new OpenLayers.Map("map_element", {}),
osm = new OpenLayers.Layer.OSM(),
vectors = new OpenLayers.Layer.Vector(),
fromProjection = new OpenLayers.Projection("EPSG:4326"),
toProjection = new OpenLayers.Projection("EPSG:900913"),
position = new OpenLayers.LonLat(6.9673223,50.9572449).transform(fromProjection, toProjection),
point = new OpenLayers.Geometry.Point(6.9673223,50.9572449).transform(fromProjection, toProjection);
map.addLayer(osm);
map.addLayer(vectors);
map.setCenter(position, 5);
pointFeature = new OpenLayers.Feature.Vector(point);
vectors.addFeatures([pointFeature]);
button.onclick = function() {
vectors.features[0].geometry.resize(1.5, point);
vectors.redraw();
};
Can you help me to figure it out ?
Thanks
http://jsfiddle.net/39KE5/1/
I haven't worked with OpenLayers much, so take everything here with a grain of salt. I was looking at this example (http://dev.openlayers.org/releases/OpenLayers-2.12/examples/resize-features.html), and I think the geometry resize does something different than what you're intending. I think what you really want to change is the style of the point. I've modified your fiddle as an example, at http://jsfiddle.net/MLundin617/39KE5/2/. It's not complete, as the click also manages to change the color of the point, but I believe it's closer to what you're looking for.
This is the major change:
radius = 2
button.onclick = function() {
radius = radius * 1.5
vectors.features[0].style = {pointRadius: radius}
vectors.redraw();
};
(Also, in your jsFiddle, you were referencing the incorrect form element, so the onclick couldn't be defined.)
Let me know if that helps. Curious to see any other answers as well.

Get a list of markers/layers within current map bounds in Leaflet

This is somewhat similar to the question asked here --
I'm writing a search box for a map application, which retrieves a whole set of search results (people's names & info) at once from a server and then pages through the list of results. So at any given point on the map there are two kinds of markers -- a background marker for points which are in the search results but not in the current page, and a foreground marker for points which are in the current page of search results.
All this works nicely.. what I'd like to do now is set it up so that if a user zooms or pans the map, the search results list updates to show only markers within the current map bounds.
Obviously there are server-side ways to do this, or I could also just run through the whole list of markers to see which fit within the current bounds; but does anybody know a built-in way to do this within leaflet? Something which would look like map.getVisibleLayers()?
I think this may be of help:
https://github.com/stefanocudini/leaflet-list-markers
as you can see from the demo, including all markers in a layer, this plugin shows a list of only those visible in the current viewport.
Its usage is simple, in a row:
var markersLayer = new L.LayerGroup();
map.addControl( new L.Control.ListMarkers({layer: markersLayer}) );
The code for obtain it is like as:
var layers = L.LayerGroup(), //layers contains all markers..
contained = []; //makers in map boundingbox
layers.eachLayer(function(l) {
if( l instanceof L.Marker && map.getBounds().contains(l.getLatLng()) )
contained.push(l);
});
Here's a fully working function that does the job:
// var map is an instance of a Leaflet map
// this function assumes you have added markers as GeoJSON to the map
// it will return an array of all features currently shown in the
// active bounding region.
function getFeaturesInView() {
var features = [];
map.eachLayer( function(layer) {
if(layer instanceof L.Marker) {
if(map.getBounds().contains(layer.getLatLng())) {
features.push(layer.feature);
}
}
});
return features;
}
You have to check the bounds of each layer versus the map's bounds. Because eachLayer() returns all layers regardless of whether they are in the visible extent.
if(map.getBounds().contains(layer.getLatLng())) { ... }
In Stefano's code, this is shown around this line:
https://github.com/stefanocudini/leaflet-list-markers/blob/master/src/leaflet-list-markers.js#L95
Regarding the last part of your question, if you want to iterate through visible layers, you can use eachLayer, e.g:
map.eachLayer(function (layer) {
// do something with the layer
});
API reference: http://leafletjs.com/reference.html#map-stuff-methods

Google Maps API V3: getBounds() convert result for fitBounds()

NO, THE ABOVE ANSWERS DON'T ANSWER MY QUESTION. PLEASE READ MY UPDATE BELOW TO SEE THE CLARIFICATION WHY THIS IS A DIFFERENT CASE!!!
I'm using Google maps API V3. When I write this code:
map.fitBounds(map.getBounds());
the map zooms out!
I understand that it's according to the documentation since fitBounds ensures to show the given bounds on the map so that all the edges are shown inside the map. Therefore, the answer I'm looking for lies into the following:
How to modify the result of getBounds to be used for fitBounds without zoom effect afterwards?
Basically, I'm quite sure this can be calculated because that's what the map does, but in the opposite direction, when adding margins, to show the given bounds completely. In these terms, tell me how to calculate the margins (and therefore, how to calculate the correct input for fitBounds having output from getBounds) and your answer will be accepted.
Thanks in advance!
Update:
Zoom and Center retrieval and setting does not work for me! here's the reason why:
I am going to hold the map's viewport information in the database. Later on, I want to re-create the map and show the exact same location again. However, the mapping platform can differ from user to user. Therefore, zoom and center is not standard between different mapping platforms/frameworks and cannot be used in all them with the same results. Therefore, the only standard way is to hold the bounds in the database. So the question needs an answer exactly in the direction it is asking for.
Store instead of the bounds the zoom and center of the map and restore these values later.
I had the exact same problem and decided to shrink the bounding box resulting from getBounds() with 15%. That does the job nicely for me:
var neLat = map.getBounds().getNorthEast().k;
var neLong = map.getBounds().getNorthEast().B;
var swLat = map.getBounds().getSouthWest().k;
var swLong = map.getBounds().getSouthWest().B;
var boundingBoxPerc = 0.15;
var mapWidth = neLong - swLong;
var mapHeight = neLat - swLat;
var ne = new google.maps.LatLng(neLat - mapHeight * boundingBoxPerc, neLong - mapWidth * boundingBoxPerc);
var sw = new google.maps.LatLng(swLat + mapHeight * boundingBoxPerc, swLong + mapWidth * boundingBoxPerc);
map.fitBounds(new google.maps.LatLngBounds(sw, ne));

Google Maps centering or marker positioning issue

I develop a simple Google Maps application. I need just to place one marker on the map. For whatever reason, the marker is placed outside of the visible area of the map. It's a little bit strange, because the map is centered to the marker's coordinates. Here is the code:
var point1 = new GLatLng(location1.lat,location1.lon);
map1.setCenter(point1, 15);
var marker1 = new GMarker(point1);
map1.addOverlay(marker1);
map1.setCenter(point1);
When we drag the map a little bit, we can see the marker. What do I need is to center the map in the way the marker will be visible without map dragging.
Can anyone help me?
I believe the GLatLng object would accept String arguments as well - but to be safe I would ensure that they are integers - try using:
new GLatLng(parseInt(location.lat), parseInt(location.lon));
I also noticed you call map.setCenter a second time which ought to not be necessary.
Using the following code really ought to do it
map=new GMap(document.getElementById("map"));
var point = new GLatLng(parseInt(location.lat), parseInt(location.lon));
map.setCenter(point,5);
var marker = new GMarker(point);
map.addOverlay(marker);
If you still are having issues I would check that "location" object to make sure the .lat and .lon values are being populated correctly.
Check this code out:
var map = new GMap(document.getElementById("map"));
/* -- snip -- */
map.centerAndZoom(new GPoint(-1.2736, 53.0705), 8);
From a website I made a while ago. Feel free to check the source:
http://www.primrose-house.co.uk/localattractions
Just click the link in the top right to switch to the map view.

Categories

Resources