When trying to define coordinates on my map, I get a different result depending if I hardcode the lon/lat or if they are coming from the database.
document.title = eventName;
document.getElementById("titleEventName").innerHTML = ol.proj.fromLonLat([5.942060,50.751453]);
document.getElementById("tempEventName").innerHTML = ol.proj.fromLonLat([eventCenterMapLongitude, eventCenterMapLatitude]);
document.getElementById("tempEventName2").innerHTML = "eventCenterMapLongitude = " + eventCenterMapLongitude + ", eventCenterMapLatitude = " + eventCenterMapLatitude;
document.getElementById("tempEventName3").innerHTML = ol.proj.transform([661467.0934630792,-4757336.459308266], 'EPSG:3857', 'EPSG:4326');
In the first line, I just display the coordinates by setting them manually. In the second line, I retrieve them from variables set out of the database. In the third line, I show the values of those variables (which are the same as the hardcoded ones). In the 4th line, I re-convert back to lat/lon, and I see that the longitude is ok, but the latitude is 90° lower than the initial latitude.
Here is the output on my screen:
661467.0934630792,6577445.839458974
661467.0934630792,-4757336.459308266
eventCenterMapLongitude = 5.942060, eventCenterMapLatitude = 50.751453
5.942060000000001,-39.24854609999999
What is wrong here? Why do I get -4757336.459308266 in the second line instead of 6577445.839458974?
It looks like you are using different coordinate systems.
See Openlayers 3 center map and http://openlayers.org/en/v3.1.1/apidoc/ol.proj.html
Related
I want to calculate the minimum distance between a point and a polyline with JavaScript and TurfJS. I can use the pointToLineDistance function for that, as follows:
var pt = turf.point([0, 0]);
var line = turf.lineString([[1, 1],[-1, 1]]);
var distance = turf.pointToLineDistance(pt, line, {units: 'miles'});
//=69.11854715938406
However, I want the LineString ('line') to be a route given by the Directions API. Therefore, I need to get the route as a set of LatLng coordinate pairs, such as:
var line = turf.lineString([
[-77.031669, 38.878605],
[-77.029609, 38.881946],
[-77.020339, 38.884084],
[-77.025661, 38.885821],
[-77.021884, 38.889563],
[-77.019824, 38.892368]
]);
The set of pairs above would form this line over Washington, DC (ignore the two markers)
How can I get a route given by the Directions API as a full set of LatLng pairs?
I tried reading through the API's documentation. You can draw polylines from routes. Assuming the polylines are drawn based on the sets of coordinate pairs of a route, they must be in there, somewhere. I just couldn't find a way to get these sets from routes.
I have a bunch of markers stored in a mysql database in a table with these attributes id,longitude,latitude.
With an ajax query I get these rows and print to console and they're exactly equal to the ones in the db.
When I create my features with openlayers, with the longitude and latitude retrieved from the db and stored in javascript variables, I don't understand why the markers are placed to another place (they're supposed to be in Italy and they are under Africa).
The interesting thing is that if I manually insert the coordinates while creating the features they show in the right place.
Browsing the internet and trying to debug my code I found some clues.
First, it may be cause of how I store longitude and latitude in the db. I saw there's someone who says DECIMAL(10,8) for latitude and DECIMAL(11,8) for longitude but all of my coordinates are similar to lon: 9.728068 and lat: 44.106414 so i decided to use DECIMAL(7,6) for longitude and DECIMAL(8,6) for latitude.
Second, if I try to console.log the data retrieved from the db I get the right coordinates e.g. 9.728068 and 44.106414 but if I get the coordinates from the features after I created them I get different values.
For the manually inserted coordinates, I get the exact same values, but for the other one no.
Here's a snippet of my code. It's a for loop that in this case will cicle 2 times
var lon = r[i]["Sensor_longitude"]; //getting longitude from success response
var lat = r[i]["Sensor_latitude"]; //getting latitude from success response
console.log(lon); //first time 9.728068, second time 9.728368
console.log(lat); //first and second time 44.106414
//using retrieved coordinates to create the feature
var areaFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326', 'EPSG:3857')),
name: sniffer_name
});
//trying to put manually the coordinates
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([9.728068,44.106414], 'EPSG:4326', 'EPSG:3857')),
name: sniffer_name
});
console.log(ol.proj.transform(areaFeature.getGeometry().getCoordinates(),'EPSG:3857','EPSG:4326'));
console.log(ol.proj.transform(iconFeature.getGeometry().getCoordinates(),'EPSG:3857','EPSG:4326'));
I have 2 entries in my db which have
lon:9.728068, lat:44.106414
lon:9.728368 ,lat:44.106414
so I will make 4 markers (areaFeature and iconFeature for each entry). areaFeature has the coordinates retrieved from db and iconFeature has coordinates inserted manually.
I expected the first half of logs to be 9.728068, 44.106414 and the second one to be 9.728368, 44.106414 but instead I get this:
9.728068 //correct
44.106414 //correct
[9.728068, -45.893585099999996] //[correct,wrong]
[9.728068, 44.106414] //[correct,correct]
9.728368 //correct
44.106414 //correct
[9.728367999999998, -45.893585099999996] //[wrong,wrong]
[9.728068, 44.106414] //[correct,correct]
As you can see latitude is nearly correct (don't know why it adds so many digits after the point) but it is negative and longitude in the first case is correct but in the second one it has other digits in addition.
I'm working on a dynamic map API which you can set as you like to. After a person puts in the name of his place I can get the viewport latitude and longitude. First of all, I get 2 values and second they are are both off according to the real coordinates. I see the result back to my own map API as well.
After much confusing I started to compare the 2 and divide them. This still gives a wrong integer.
With this I get the values which are coupled to the name that has been given.
google.maps.event.addDomListener(searchBox, 'places_changed', function(event) {
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
bounds.extend(place.geometry.location);
marker.setPosition(place.geometry.location);
for(key in places) {
if(places.hasOwnProperty(key)) {
var value = places[key];
var geoLong = value.geometry.viewport.b.b;
var geoLat = value.geometry.viewport.f.f;
Example:
Empire State builiding: Real coordinates: 40.748817, -73.985428.
My results: latitude: 40.746983 and 40.749681 : longitude -73.983858 and -73.986556.
This is from geometry.viewport.b.(b or f) and geometry.viewport.f.(b or f) That's how I retrieved the information.
Possible solution:
After much try and error of getting the right results, I stumbled onto this.
google.maps.event.addListener(map, 'click', function(event){
console.log( "Latitude: "+event.latLng.lat()+" "+", longitude: "+event.latLng.lng() );
});
While this is giving the right value back I can't call it like I did with the other 2. It keeps saying that latLng is undefined and that is true because it doesn't work with the objects/array which is given by places.
Question: How come that the viewport is giving a different value then the real coordinates?
If I understand correctly, your intention is to get the position of the place from Google database.
I would suggest following the official API reference documentation and avoid using things like viewport.b.b or viewport.f.f in your code. Note that once Google updates the version of the API these undocumented properties might change their names.
If you check the documentation you will see that getPlaces() method of search box returns an Array<PlaceResult> result.
https://developers.google.com/maps/documentation/javascript/reference#SearchBox
So, var value in your code has type PlaceResult that is documented here:
https://developers.google.com/maps/documentation/javascript/reference#PlaceResult
The geometry property of place result has a PlaceGeometry type that is documented here:
https://developers.google.com/maps/documentation/javascript/reference#PlaceGeometry
That means that in order to get position of the place you should execute the following code
var value = places[key];
var geoLong = value.geometry.location.lng();
var geoLat = value.geometry.location.lat();
I hope this helps!
I am using nokia.places.widget.SearchBox together with nokia.maps.map.Display.
You can use onSelect function of the SearchBox to perform operations when a user picks an items from the results list.
What I need to do is center and zoom the map to the picked place. My problem is concerning zooming because I don't know what level to use.
I noticed that some places have boundingBox (to use with the zoomTo function of the Display component) property but other doesn't. I could use category ('administrative-region', 'street-square', etc.) but it is other than precise and moreover I can't find a list of possible category codes.
Any suggestion?
To get the map to move/zoom to a location when a suggestion is chosen, you will need to implement an onResults handler:
var fromSearchBox = new nokia.places.widgets.SearchBox({
targetNode: "fromSearchBox",
template: "fromSearchBox",
map: map,
onResults: function (data) {
// Your code goes here //
}
});
As you noticed the data field may or may not hold a bounding box. This is because only a few locations cover a defined area, most are point addresses.
For the subset which have a boundingbox you can do the following:
if (data.results.items[0].boundingBox){
map.zoomTo(data.results.items[0].getBoundingBox());
}
For the remainder the answer will depend upon what you are trying to achieve, but you could try any of the following:
Move to the location on the map without altering the zoom. (i.e. let the user decide)
map.set("center", data.results.items[0].position);
Move to the specified bounding box for a point object at the
specified location.
var obj = new nokia.maps.map.StandardMarker(startPoint);
map.zoomTo(obj.getBoundingBox());
Or alternatively: map.zoomTo(nokia.maps.geo.BoundingBox.coverAll([startPoint]));
Define a bounding box surrounding the point location and zoom to that instead
startPoint =data.results.items[0].position;
bottomLeft = new nokia.maps.geo.Coordinate(startPoint.latitude - 0.1,
startPoint.longitude + 0.1);
topRight = new nokia.maps.geo.Coordinate(startPoint.latitude + 0.1,
startPoint.longitude - 0.1);
map.zoomTo(nokia.maps.geo.BoundingBox.coverAll([topRight, bottomLeft]));
Additionally, Display.zoomTo() can also take an additional parameter, so if you use map.zoomTo(BoundingBox, true) you will also keep the current center for the map on screen, and this may give more context to a user.
I want to browse a single image with the Google Maps API, for which I've defined my own projection. I wanted to use a GroundOverlay instead of several image tiles, because I only have one small-resolution image, but I wanted it to still be zoomable. However, I get some erratic behavior when trying to work with this projection:
No overlays show up at all at zoom level 0.
At zoom level 1 and higher, Markers show up, but GroundOverlays still don't.
However, I can get GroundOverlays to show up very briefly, if I zoom out from any level. It will only show while it's zooming out and disappear again immediately. Also, while it does show up shortly, it does not show up at the right coordinates, but the Markers do.
I'm rather new to the API, so I would not be surprised if it was a simple oversight on my part, but I just can't see what could cause this. Here is the code for my projection, which just maps the lat/lng linearly to map coordinates:
function EvenMapProjection() {
var xPerLng = 512/360;
var yPerLat = 512/180;
this.fromLatLngToPoint = function(latlng) {
var x = (latlng.lng()+180)*xPerLng;
var y = (latlng.lat()+90)*yPerLat;
console.log('Lng', latlng.lng(), 'Lat', latlng.lat(), '-> Point', x, y);
return new google.maps.Point(x, y);
};
this.fromPointToLatLng = function(point) {
var lat = point.y/yPerLat-90;
var lng = point.x/xPerLng-180;
console.log('Point', point.x, point.y, '-> Lng', lng, lat);
return new google.maps.LatLng(lat, lng);
};
}
An example of what I'm trying to do without the projection (using the default Mercator projection):
http://95.156.209.71/tmp/a.html
The same example with the projection as defined above:
http://95.156.209.71/tmp/b.html
And finally an example using the projection but without the GroundOverlay, and instead just using tiled images (always the same image):
http://95.156.209.71/tmp/c.html
The last link also shows the Marker at LatLng(0, 0) appear at zoom level 1 (or higher), but not at level 0.
Is there something I'm just missing, or some buggy code, or is this actually a problem in the API?
I just found out that my mistake was in the definition of the ground overlay. I was at zoom level 0, which meant that I set the bounds for the overlay from (-90,-180) to (90,180), but the API seems to have issues with these levels, because they wrap longitude, hence I got weird errors. I adjusted it to be at level 1 for minimum zoom, and set the overlay from (-45,-90) to (45,90), and now it all works fine.