I wonder, how can I get map click event's coordinates as lat,lon?
Here is my code:
map.on('click', function(evt) {
var element = popup.getElement();
var coordinate = evt.coordinate;
var latLon = ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326');
$(element).popover('destroy');
popup.setPosition(coordinate);
Normally, coordinate value gives me an array etc: [48654.02545, 3265468.45455]
But I need lat lon etc:([39,54876,32,547821])
Abstract: I need to convert epsg:3857 coordinate to epsg:4326 coordinate (lat/lon)
Any idea?
If your map view projection is Web Mercator (EPSG:3857), which is the default, then the following should work:
map.on('click', function(evt) {
var lonlat = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
var lon = lonlat[0];
var lat = lonlat[1];
// …
});
Related
I would like to export as csv of NDVI time series for different points. I currently have a code that can print a chart, then click download the data from chart. Is there a better way to do so as I do not necessarily need to open a chart?
What I have now is a code to print a chart for one location, then I could download...I would like to have an automatic way so that I will not need to download from chart.
var point = ee.Geometry.Point([-100, 50]);
var LS8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');
var FieldLS8 = LS8.filterBounds(point).filterDate('1995-01-01', '2018-12-31').sort('CLOUD_COVER')
var cloudlessNDVI_LS8 = FieldLS8.map(function(image) {
var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');
var mask = cloud.lte(50);
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi).updateMask(mask);
});
print(ui.Chart.image.series({
imageCollection: cloudlessNDVI_LS8.select('NDVI'),
region: point,
reducer: ee.Reducer.first(),
scale: 30
}).setOptions({title: 'LS8: Meadow Cloud-masked NDVI over time'}));
You can do it with the .getRegion command. It outputs an Array with all the values overlapping your geometry, so you can use multipoint geometries as well.
The difficulty is in exporting it, since only FeatureCollections can be exported. That's why you need to convert it to a FeatureCollection to export it.
var points = ee.Geometry.MultiPoint(
[[16.5, 11.3],
[20.9, -14.5]]);
var LS8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');
var FieldLS8 = LS8.filterBounds(points).filterDate('1995-01-01', '2018-12-31').sort('CLOUD_COVER')
var cloudlessNDVI_LS8 = FieldLS8.map(function(image) {
var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');
var mask = cloud.lte(50);
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi).updateMask(mask);
});
var poiArray = cloudlessNDVI_LS8.select('NDVI').getRegion(points, 30);
var names = poiArray.get(0)
var values = poiArray.slice(1)
var exportFC = ee.FeatureCollection(
values.map(function(values){
return ee.Feature(null, ee.Dictionary.fromLists(names, ee.List(values)))
})
)
var sortedFC = exportFC.sort('id')
print(sortedFC)
Export.table.toDrive(sortedFC)
You will get an Array with the lon/lat of the point as an identifier, which you could group your graphs by.
I have the following array which is loaded up with businesses:
var businessesArray = [Business]()
Now each Business has a latitude and longitude attribute:
private var _latitude: Double
private var _longitude: Double
What is the most efficient way (using swift) to sort businessesArray by putting business closest to the user at the start and farthest from the user at the end (sorted from nearest to farthest)? Assume I already have the user's current location in these variables:
var currentUserLatitude: Double
var currentUserLongitude: Double
Given this struct (you can also use a class)
struct Business {
let latitude: Double
let longitude: Double
var location: CLLocation {
return CLLocation(latitude: latitude, longitude: longitude)
}
}
The user location
var currentUserLatitude: Double = ...
var currentUserLongitude: Double = ...
let userLocaton = CLLocation(
latitude: currentUserLatitude,
longitude: currentUserLongitude
)
And a list of places
let places: [Business] = ...
This is how you sort them
let sortedPlaces = places.sort {
userLocaton.distanceFromLocation($0.0.location) < userLocaton.distanceFromLocation($0.1.location)
}
Or if you prefer the extended notation code
let sortedPlaces = places.sort { (left, right) -> Bool in
userLocaton.distanceFromLocation(left.location) < userLocaton.distanceFromLocation(right.location)
}
How does it work?
The sort method accepts a closure.
Inside this closure you must specify the sorting logic. More specifically, given 2 Business values left and right, if left should be placed before right in the final sorting then the closure returns true. Otherwise false.
You can use the CLLocation class and it's distanceFromLocation method to calculate the distances from the current location.
Extending the Business model
extension Business {
var location: CLLocation {
return CLLocation(latitude: self.latitude, longitude: self.longitude)
}
}
Sorting the places array
let userLocaton = CLLocation(latitude: currentUserLatitude, longitude: currentUserLongitude)
let sortedPlaces = places.sort { (left, right) -> Bool in
userLocation.distanceFromLocation(left.location) < userLocation.distanceFromLocation(right.location))
}
Inside Business create a computed variable like so
var distanceFromUser: Double {
return pow((userLat - _latitude), 2) + pow((userLon - _longitude), 2)
}
then where you have your array of Businesses call
businessesArray.sort({ $0.distanceFromUser < $1.distanceFromUser})
I know the earth isn't flat, but Pythagorean Theorem still works as intended. You never need to take the square root, because obviously if a > b then sqrt(a) > sqrt(b), and you don't have to take the abs because squaring them does it for you :)
I search a method to find if my current location is on the path define by aPolyline.
In google maps a function exist isLocationOnEdge, but I cannot find a similar function in Here maps API.
This could be achieved using an approach an below
//global variable
var polyline;
polyline = new H.map.Polyline(strip);
map.addObject(polyline);
function liesOnPolyline(coords){
// get objects at the coordinates (pixel coordinates, can be converted from lat, lon using map.geoToScreen )
var objects = map.getObjectsAt(coords.x, coords.y);
// iterate through the array to check if polyline can be retrieved here
var withinPolyline = false;
for (var object in objects) {
if(objects[object] === polyline){
withinPolyline = true;
break;
}
}
console.log("lies within Polyline"+withinPolyline );
}
I run this code to get all of my vector coordinates:
var ft = vectorSource[0].getFeatures();
for(var i=0; i< ft.length; i++){
document.getElementById('abc').innerHTML+=vectorSource[0].getFeatures()[i].getGeometry().transform('EPSG:3857','EPSG:4326').getCoordinates()
};
This is the result:
106.68594471683284,-6.145608605008391,106.68637254034257,-6.145584973628701
How can I get two numbers representing lon & lat from my vector?
i need result coordinate like following code from all my vector but without click the map
map.on('singleclick', function(evt) {
var coordinate = evt.coordinate;
});
I am trying to create a Google Map with a single coordinate as marker. I use ASP MVC, and the coordinates are saved in the database as a string.
<%: Model.LatLng %>
outputs something like this: 52.425, 4.938
The problem is, Google Maps cannot read this, probably because it is a string. How do I convert the coordinates to something Google Maps can read?
Google map code (just default example)
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Hello World!"
});
mylatlng needs to be <%: Model.LatLng %> but since its a string it won't work.
Got the anwser:
var LatLng = "<%: Model.LatLng %>";
var latlngparts = LatLng.split(",");
var latlng = new google.maps.LatLng(parseFloat(latlngparts[0]), parseFloat(latlngparts[1]));