Openlayers - Projection issues when getting latitude/longitude from a point - javascript

I'm trying to get the latitude/longitude from a draggable marker with Openlayers and OSM but I can't find the good settings for the projection conversion, what I am doing wrong ?
Here is the code: http://pastie.org/2300321 (see addMarker l140 & updateTargets l153) & and a little demo test.
If you submit an address, then drag the marker, the longitude and latitude are wrong. I tested a few different projections but I'm not sure what I've to useā€¦

I think the problem is inside updateTargets method:
var point = this.feature.geometry;
var pixel = new OpenLayers.Pixel(point.x, point.y);
var coord = this.map.getLonLatFromPixel(pixel).transform(
new OpenLayers.Projection("EPSG:900913"),
new OpenLayers.Projection("EPSG:4326")
);
this.feature.geometry is already specified in lon/lat coordinates, not in pixels. So I suggest that you skip second line and do the conversion from OpenStreetMap projection to lon/lat directly on geometry object:
var coord = this.feature.geometry.transform(
new OpenLayers.Projection("EPSG:900913"),
new OpenLayers.Projection("EPSG:4326")
);

Related

Fitting map bounds to raster layer

I've ran across all fitbounds tutorials for Mapbox and still cannot figure out how refocus my map on a given raster layer. I have a menu that toggles a number of older maps and would like to refit the map at each turn.
Here's what I have so far. mapnumber is the string for my raster map.
var coordinates = map.getBounds(mapnumber);
var bounds = new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]);
map.fitBounds({bounds});
The bounds are there, I just cannot use fitbounds on them. This is the error.
lng_lat.js:97 Uncaught Error: `LngLatLike` argument must be specified
as a LngLat instance, an object {lng: <lng>, lat: <lat>}, or an array
of [<lng>, <lat>]
Uncaught Error: LngLatLike argument must be specified
as a LngLat instance
It looks like you're using mapboxgl.LngLatBounds incorrectly. You'll need to pass in two LngLat instances, rather than two coordinates. The API docs have an example that creates a point for the southwest and northeast corners of your bounding box:
var sw = new mapboxgl.LngLat(-73.9876, 40.7661);
var ne = new mapboxgl.LngLat(-73.9397, 40.8002);
var llb = new mapboxgl.LngLatBounds(sw, ne);
Then you can use map.fitBounds() with the bounding box
map.fitBounds(llb);
UPDATE: answering follow up question
how can I extract the two sets (sw and ne) from the raster?
You can use the map.getSource() method. Pass in the source ID of your raster layer and that will return an object that has a bounds property. Use this bounds property to pass into map.fitBounds().
var bounds = map.getSource('mapbox://username.source-id').bounds;
map.fitBounds(bounds);
Here's a working example: https://codepen.io/mapsam/pen/RZvyBQ

Google maps LatLng and LatLngBounds returning different results

I'm currently learning to use google maps and am following the following to set a max bound for my map: Google Maps v3 - limit viewable area and zoom level
My bounds are set as:
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(41.600, -87.857),
new google.maps.LatLng(42.065, -87.310)
)
Within my dragend event listener, I console.log(strictBounds) and am getting the following:
It is returning my south-west Latitude and north-east Latitude together as one LatLng and my south-west Longitude and north-east Longitude as one LatLng.
I could sorta hack it and set south-west and north-east coordinates so that the return would be what I want it to be, but I was wondering why this is happening in this scenario and would I be running into this problem further with other google map methods?
EDIT:
Just to clarify, my two LatLng positions set in strictBounds should be my southWest and northEast positions for the max bounds of the map.
When I use the addListener method provided in the link above (Google Maps v3 - limit viewable area and zoom level), it grabs the wrong lat/long from strictBounds.
Instead of grabbing:
(41.6, -87.857), (42.065, -87.310)
It grabs:
(41.6, 42.065), (-87.31, -87.856999..)
The way you define the bound is correct. Just don't use console.log(strictBounds). Use the following instead
var sw = strictBounds.getSouthWest();
var ne = strictBounds.getNorthEast();
console.log(sw.lat() + "," + sw.lng());
console.log(ne.lat() + "," + ne.lng());

Openlayers - Getting Incorrect LonLat while transform?

I have trying to get Latitude and Longitude of a Point.
But While transforming it's not returning the correct LonLat. It's big number that is not a lonlat point for sure.
I have tried for some solutions but didn't get result.
What else could be failing?
JS Code I have Tried
map = createMap("deviceMap");
var fromProjection = new OpenLayers.Projection("EPSG:4326");
var toProjection = new OpenLayers.Projection("EPSG:900913");
map.events.register('click', map, function handleMapClick(e) {
lonLat = self.map.getLonLatFromViewPortPx(e.xy).
transform(map.getProjectionObject(), toProjection);
prompt("",lonLat);
});
Finally got answer
map.events.register('click', map, function handleMapClick(e) {
var toProjection = new OpenLayers.Projection("EPSG:4326");
var lonLat = map.getLonLatFromPixel(e.xy).
transform(map.getProjectionObject(), toProjection);
});
EPSG:4326
should refer to WGS 84,
has decimal degree values
EPSG:900913
refers to WGS84 Web Mercator
has metric values, it is x/y axis coordinate system, so "high numbers" are expected
If I understand you right, you should have in variable lonLat a high number.
"LonLat" in OpenLayers does not mean, it will be only longitude/latitude, see documentation here:
lon {Number} The x-axis coordinate in map units. If your map is in a
geographic projection, this will be the Longitude. Otherwise, it will
be the x coordinate of the map location in your map units.
lat {Number} The y-axis coordinate in map units. If your map is in a
geographic projection, this will be the Latitude. Otherwise, it will
be the y coordinate of the map location in your map units.
So if you want to get a real LonLat coordinates, you should not convert it (and use EPSG:4326) or convert it to the other coordinate system, not EPSG:900913.
By the way, OpenLayers started to use 900918 (numeric equivalent to GOOGlE), It was define by Mr. Christopher Schmidt, firstly it was not accepted by European Petroleum Survey Group (EPSG). Then EPSG changed their mind and gave them number: 3857 - WGS84 Pseudo-Mercator.

OpenLayers LonLat transform

I want to use decimal Lon and Lat like Google Maps uses. But it seems I need to transform the LonLat object in OpenLayers, e.g.
var map, layer;
function init(){
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
map.addLayer(layer);
map.setCenter(
new OpenLayers.LonLat(-1.60400390625, 54.07228265560386).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 6
);
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(0,0);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(-1.60400390625, 54.07228265560386).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject()),icon));
}
Each time I place a marker the position needs to be transformed to EPSG:4326. Is there a way to tell the map to always use this projection?
Whether you can set the projection on a map or not, depends on which service you are using for the base layer. As far as I know, OSM only provides its rendered tiles in EPSG:900913, so there is no way around transforming your coordinates before adding them to the map. You could search for a service that provides its tiles in multiple projections, but I haven't seen one that is free to use so far. An alternative would be to render your own tiles in the needed projection and provide them through your own tile server.
Let's suppose you have such a map, you can change the projection using OpenLayers.Map.setOptions() like this:
map.setOptions({
projection: "EPSG:4326"
});
But you may also need to set some projection related properties, like maxExtent etc. See this question.

How to get screen XY from Google maps (V3) LatLng?

I have polyline in my map. I want to know the pixel (screen) xy-coordinates, when user clicks the polyline. Click event only returns the LatLng object, so does anyone have a clue how to get the pixel coordinates from latLng?
I would appreciate very much if someone could help me!
If you have the LatLng object, you can use the google map projection object to transform it into tile coordinates and then into pixel coordinates:
For the docs on the projection class:
https://developers.google.com/maps/documentation/javascript/reference#Projection
Google's example explaining how to transform a LatLng into a pixel coordinate:
https://developers.google.com/maps/documentation/javascript/examples/map-coordinates?csw=1
There's one catch. The above will give you the pixel coordinates inside google's map div (which you may want depending on your needs). If you want the pixels relative to the top left corner of the screen, there's one more step. You need to do the same projection on the the viewport's top left corner and subtract the two. This will give you the pixel coordinates of the LatLng point.
The code I finally used looked like this (note that "latLng" is an input):
var numTiles = 1 << map.getZoom();
var projection = map.getProjection();
var worldCoordinate = projection.fromLatLngToPoint(latLng);
var pixelCoordinate = new google.maps.Point(
worldCoordinate.x * numTiles,
worldCoordinate.y * numTiles);
var topLeft = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var topLeftWorldCoordinate = projection.fromLatLngToPoint(topLeft);
var topLeftPixelCoordinate = new google.maps.Point(
topLeftWorldCoordinate.x * numTiles,
topLeftWorldCoordinate.y * numTiles);
return new google.maps.Point(
pixelCoordinate.x - topLeftPixelCoordinate.x,
pixelCoordinate.y - topLeftPixelCoordinate.y
)

Categories

Resources