Openlayers 3.6: Getting the center of the current map view - openlayers-3

I'm trying to get the current center of an Openlayers map in lat/lon coordinates. I've got the following event handler setup:
this.map.on('pointermove', function (e) {
if (e.dragging) {
console.log(that.map.getView().getCenter());
}
});
This works, but I'm getting weird values. Here's an example:
[9318218.659044644, 3274618.6225819485]
Those are obviously not lat/lon values :) Do I need to transform this somehow? Thanks!

I'm not super familiar with openlayers but it sounds like the map is in different projection.
Check out the following on spherical_mercator, transform,
Open Layers projections
UPDATED
I've done a little more research, check out this example. Not sure what the projection your view is in. the map in this example is in ''EPSG:21781' if you go to a js console and enter map.getView().getCenter() you get [693230.7161150641, 179010.3389264635] but if you enter ol.proj.transform(map.getView().getCenter(), 'EPSG:21781', 'EPSG:4326') you get [8.658936030357363, 46.75575224283748] hope that helps.

For those who are working with angular.
Also, I would consider searching the projection of the map, instead of entering it manually.
import * as olProj from 'ol/proj'
import Map from 'ol/Map'
// ...
olProj.transform(
this.map.getView().getCenter(),
this.map.getView().getProjection(),
'EPSG:4326',
)

Update for OpenLayers 6 (assuming your map is called 'map') the following gives an array of [lon, lat] for the centre of your map's view.
ol.proj.toLonLat( map.getView().getCenter() )

Related

Mapbox GL JS : Popup onclick with external JSON

I am trying to display a popup onclick in Mapbox GL JS when the user clicks a polygon (It's a weather warning box during a Flash Flood Warning).
I have been using this example from Mapbox as a base, and -
This is my JSON file that I am trying to pull data from.
When I click the polygon, there is no popup. When I mouseover it, the cursor changes - so I know the basic possible issues like filename and directory structure are right.
My code below was modified from the example. I am trying to load the "description" of each polygon : (My map is called "topleftmapbox" and the JSON id is "FFWWarning")
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
topleftmapbox.on('click', 'FFWWarning', function (e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var description = e.features[0].description;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(topleftmapbox);
});
// The following code below runs correctly and changes the cursor on mouseover.
topleftmapbox.on('mouseenter', 'FFWWarning', function () {
topleftmapbox.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
topleftmapbox.on('mouseleave', 'FFWWarning', function () {
topleftmapbox.getCanvas().style.cursor = '';
});
I have a feeling that my issue is somewhere in this part of the code :
var coordinates = e.features[0].geometry.coordinates.slice();
var description = e.features[0].description;
I am still new with Mapbox and I have tried looking through here and various sources online to fix this. I am hoping the issue is just that I have the description variable set wrong and that I am missing something simple.
I debugged the code that you provided and found that variable coordinates was containing an object having array of lat-lng.
Modifying that part should fix the issue.
var coordinates = e.features[0].geometry.coordinates[0][0].slice();
In coordinates[0][0], second index determines the position of popup.
Here is the working code. https://jsbin.com/suzapug/1/edit?html,output

Update Mapbox direction instructions while driving/walking + add direction indicator

I'm building a web app to view featured walking routes in my neighbourhood.
User opens the app and sees all different routes.
App gets current location and checks for most nearby route.
App requests the route to one of my featured routes.
User can use the app to navigate to a marker from my featured route that is most nearby.
I'm working with the Directions Service which can give me a list of walking instructions like this:
I'm now trying to combine the directions with my current location. What is the best option to do this? I want to update the instructions based on my current location so for example if I head east on the Amstelkade I want to see the next instruction at the top. I came up with the following:
Add GeolocateControl to Mapbox
let geolocate = new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
})
map.addControl(geolocate);
Put a listener on the geolocate change event and update starting place (origin) to get the latest direction instructions.
geolocate.on('geolocate', function(location) {
currentLocation = location;
setOrigin(location);
setDestination(location);
});
function setOrigin(location){
if(Object.keys(directions.getOrigin()).length === 0){
directions.setOrigin([location.coords.longitude, location.coords.latitude]);
}
}
I'm a little bit lost if this is a proper solution because in this way i'm making a lot of requests (could put a debouncer on the geolocate event though). Is there a better way to solve this and make it more user friendly?
Question 2: is it possible to add a direction indicator (blue beam of direction you're heading) to Mapbox like Google does?
Thanks all!

How can I get the polygon clicked on in ti.map on iOS?

I have a simple map where I draw some polygons. Then I want to capture if the user clicks on a polygon - and get a handle to that polygon (e.g. by a custom id of the polygon or similar).
I use code like this to add the polygon:
var poly = Map.createPolygon({
points : points,
id : 'poly',
fillColor : '#55ec858f',
strokeColor : 'black',
strokeWidth : 2
});
mapView.addPolygon(poly);
where points is an array of latitude/longitude objects. I have registered a click handler:
mapView.addEventListener('click',clickHandler);
... and it is defined like this:
function clickHandler(e){
console.log("click: id=" + e.source.id + ", source=" + JSON.stringify(e.source));
console.log("click: clicksource=" + e.clicksource + ", latitude=" + e.latitude + ", longitude=" + e.longitude);
}
The click handler is triggered once I click within the polygon (well, more correctly it is triggered wherever on the map I click). This is fine. However, on iOS I cannot identify which of the polygons the user clicked on. The output looks like this:
[INFO] : click: id=undefined, source={"horizontalWrap":true,"visible":true,"mapType":1,"rotateEnabled":false,"region":{"longitudeDelta":0.010248234495520592,"latitudeDelta":0.009999999776482582,"longitude":11.154247283935547,"latitude":55.55887985229492}}
[INFO] : click: clicksource=polygon, latitude=55.55712556278878, longitude=11.154479577247997
On Android I get what I want:
[INFO] : click: id=poly, source={"fillColor":"#55ec858f","strokeColor":"black","points":[{"latitude":55.563299,"longitude":11.157998},{"latitude":55.562731,"longitude":11.157987},{"latitude":55.562719,"longitude":11.158029},{"latitude":55.562648,"longitude":11.158027},{"latitude":55.562153,"longitude":11.157851},{"latitude":55.561301,"longitude":11.157834},{"latitude":55.561088,"longitude":11.157913},{"latitude":55.560212,"longitude":11.157896},{"latitude":55.560106,"longitude":11.157935},{"latitude":55.559751,"longitude":11.157928},{"latitude":55.559515,"longitude":11.157882},{"latitude":55.559267,"longitude":11.157731},{"latitude":55.559184,"longitude":11.15775},{"latitude":55.559018,"longitude":11.15783},{"latitude":55.558899,"longitude":11.157953},{"latitude":55.558686,"longitude":11.157928},{"latitude":55.558604,"longitude":11.157864},{"latitude":55.558391,"longitude":11.157859},{"latitude":55.558143,"longitude":11.157834},{"latitude":55.557694,"longitude":11.157804},{"latitude":55.557233,"longitude":11.15769},{"latitude":55.556985,"longitude":11.157623},{"latitude":55.556678,"longitude":11.157513},{"latitude":55.556266,"longitude":11.157317},{"latitude":55.556041,"longitude":11.157291},{"latitude":55.555828,"longitude":11.157245},{"latitude":55.555592,"longitude":11.157157},{"latitude":55.555144,"longitude":11.156961},{"latitude":55.554779,"longitude":11.156786},{"latitude":55.554507,"longitude":11.156677},{"latitude":55.554401,"longitude":11.156675},{"latitude":55.554366,"longitude":11.156632},{"latitude":55.554385,"longitude":11.156451},{"latitude":55.554447,"longitude":11.155964},{"latitude":55.554525,"longitude":11.155484},{"latitude":55.554621,"longitude":11.155014},{"latitude":55.554733,"longitude":11.154556},{"latitude":55.554862,"longitude":11.154111},{"latitude":55.555005,"longitude":11.153681},{"latitude":55.555164,"longitude":11.153268},{"latitude":55.555337,"longitude":11.152873},{"latitude":55.555524,"longitude":11.152498},{"latitude":55.555724,"longitude":11.152145},{"latitude":55.555936,"longitude":11.151815},{"latitude":55.556159,"longitude":11.151509},{"latitude":55.556393,"longitude":11.151228},{"latitude":55.556636,"longitude":11.150974},{"latitude":55.556887,"longitude":11.150747},{"latitude":55.557147,"longitude":11.150549},{"latitude":55.557412,"longitude":11.150379},{"latitude":55.557684,"longitude":11.15024},{"latitude":55.557959,"longitude":11.150131},{"latitude":55.558238,"longitude":11.150053},{"latitude":55.55852,"longitude":11.150006},{"latitude":55.558802,"longitude":11.14999},{"latitude":55.559084,"longitude":11.150006},{"latitude":55.559366,"longitude":11.150053},{"latitude":55.559645,"longitude":11.150131},{"latitude":55.55992,"longitude":11.15024},{"latitude":55.560192,"longitude":11.150379},{"latitude":55.560457,"longitude":11.150549},{"latitude":55.560717,"longitude":11.150747},{"latitude":55.560968,"longitude":11.150974},{"latitude":55.561211,"longitude":11.151228},{"latitude":55.561445,"longitude":11.151509},{"latitude":55.561668,"longitude":11.151815},{"latitude
[INFO] : click: clicksource=polygon, latitude=55.55844486621942, longitude=11.154376566410065
The id is really enough for me to get the relevant data (and be able to show the user some more details about the area).
I have tried to add an event handler to the polygon - but it does not work (and really I would want to use one global event listener as in the example above).
I think the only thing I have not tried yet is to try to calculate which polygon I am inside based on the GPS points... I am not really good at such geometric arithmetic - so would like not to go down that road if possible ;-)
Any good ideas?
Thanks in advance!
Edited:
Forgot to mention platform...
Appc CLI 5.1.0
Studio: 4.4.0
ti.map: 2.3.6 (Android)
ti.map: 2.5.2 (iOS)
/John
You can use e.shape.title
I do it like this:
map.addEventListener('click', function(e) {
Ti.API.info('You clicked ' + JSON.stringify(e.shape.title));
});
I can't remember what is available on the e.shape, but i guess you should be able to find an id, or something else to identify your polygon.

Implementing a search function for a marker

I have Markers setup with gmaps4rails.
Now I want to implement a classic search function.
If I find one object, it should directly show the marker.infowindow
How do I open it directly?
I tried:
function focusSearch() {
handler.map.centerOn({ lat: <%=#searchy.latitude %>, lng: <%=#searchy.longitude %>});
handler.getMap().setZoom(16);
marker = <%=#searchy.id%>
marker.infowindow.open(map, marker.serviceObject);
}
But I guess I am going wrong there...
Anyone can help?
If you have an Idea how to directly use the #search:params, I am happy!
Thanks for helping out!
I've created a plunkr with working code here.
Basically steps are:
associate the marker to the original json data where ids are available
search the marker list for the id you expect
trigger the 'click' google map event on the marker which triggers pan + infowindow

How to register map move / map pan events in OpenLayers 3

I'm looking for OpenLayer 3 map event for map move/map pan, something like:
map.on('move', function(){
...
}
Does anyone know how to implement?
The moveend event might be the one you search for - it detects any move made, even those not invoked by dragging.
map.on('moveend', function (e) {
console.log("moved");
});
See http://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html
UPDATE:
These events are no longer present in recent versions. Please refer to the more recent answer for an up-to-date information.
Names of the events you're looking for are drag and/or dragend (it's probably a better idea to depend on properties names, though: ol.MapBrowserEvent.EventType.DRAG but it didn't work on the demo page):
map.on('drag', function() {
console.log('Dragging...');
});
map.on('dragend', function() {
console.log('Dragging ended.');
});
Reverse-engineered by looking inside mapbrowserevent.js, the documentation explicitly mentions events are not documented yet.
MoveEnd trigger if u move the map with a script.
I have use that in OpenLayers 6:
map.on('pointerdrag', function (event) {
is_map_center = false;
})
hf gl!
I believe this functionality exists in 2 functions within the View of a map, not the map itself. You can monitor the center property of the View by listening for change:center events. There is also a getInteracting() method in ol.View that will return a boolean if an interaction (zooming or panning) is occurring.
https://openlayers.org/en/v4.6.5/apidoc/ol.View.html#getInteracting

Resources