how can I export only the coordinates (only longitude and latitude ) of non masked pixel in CSV format in google earth engine (gee)? - coordinates

From the code below, I would like to export only longitude and latitude coordinates in a CSV format. (having just the two columns corresponding to pixel coordinates). Like in the picture:
I mean just the coordinates of the image "img"
var roi = ee.Geometry.Polygon(
[[[-120.49004321754768, 40.25395755396244],
[-120.49004321754768, 40.144869571147176],
[-120.31975513161018, 40.144869571147176],
[-120.31975513161018, 40.25395755396244]]], null, false);
var lan= ee.ImageCollection("LANDSAT/LC08/C02/T1_L2").filterBounds(roi).first().select('SR_B2').clip(roi);
var img= (lan.gt(14000)).selfMask();
var vis_B2 = {
min: 8217,
max: 16204,
};
Map.centerObject(roi);
Map.addLayer(lan, vis_B2, 'True Color (432)');
Map.addLayer(img, {palette:'red'}, 'Img');

Related

Converting from WGS84 to EPSG:27700 raster tiles without drawing a map

Using this example from OS Data Hub - https://labs.os.uk/public/os-data-hub-examples/os-maps-api/zxy-27700-basic-map
I can get a list of tiles displayed on the map, I would like to get the coordinates of the tile without drawing the map.
Starting from a single point in WGS84 (lat/long) I can convert this to EPSG:27700 using Proj4js
var source = new proj4.Proj('EPSG:4326');
proj4.defs("EPSG:27700","+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs");
var dest = new proj4.Proj('EPSG:27700');
var coords=proj4.transform(source, dest, [X,Y]);
I then need to translate this into coordinates for the raster tile, which is done in the leaflet example with this code:
var crs = new L.Proj.CRS('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs', {
resolutions: [ 896.0, 448.0, 224.0, 112.0, 56.0, 28.0, 14.0, 7.0, 3.5, 1.75 ],
origin: [ -238375.0, 1376256.0 ]
});
How can i replicate this step to produce the tile coordinates, without having to draw the leaflet map?
I ultimately want to use the coordinates to grab & save a single tile from the OS Data Hub with this format:
https://api.os.uk/maps/raster/v1/zxy/layer/%7Bz%7D/%7Bx%7D/%7By%7D.png?key=
Using the EPSG:27700 coords calculated using proj4, and the zoom level resolutions (which are meters per pixel) and tile grid origin coordinates used in the definition you can calculate the {x} and {y} values in https://api.os.uk/maps/raster/v1/zxy/layer/{z}/{x}/{y}.png?key= for any zoom level {z} based on the standard tile size of 256 pixels as
x = Math.floor((coords[0] - origin[0]) / (resolutions[z] * 256));
y = Math.floor((origin[1] - coords[1]) / (resolutions[z] * 256));

Leaflet meters to pixels per zoom level

I'm creating an app using Leaflet library
I have a field radius that contains distance in meters (m).
const radius = 1000;
I would need to convert this field to pixels, but on different zoom levels
For zoom levels, I get values from 8 till 18
I have this function that converts successfully on the current zoom level
function disToPixeldistance(distance){
var l2 = L.GeometryUtil.destination(map.getCenter(),90,distance);
var p1 = map.latLngToContainerPoint(map.getCenter())
var p2 = map.latLngToContainerPoint(l2)
return p1.distanceTo(p2)
}
But I would need to pass different zoom levels as an additional parameter and then convert them from meters to pixels
Like:
function disToPixeldistance(distance, zoomLevel)
Does anyone knows how could I achieve this ? Thank you in advance :)
Change the map.latlngToContainerPoint(latlng) to map.project(latlng,zoom)
function disToPixeldistance(distance, zoom){
zoom = zoom || map.getZoom();
var l2 = L.GeometryUtil.destination(map.getCenter(),90,distance);
var p1 = map.project(map.getCenter(), zoom)
var p2 = map.project(l2,zoom)
return p1.distanceTo(p2)
}

How can I find all the lakes in a region (bounded by polgon) in earth engine?

The problem statement is that a region of interest is given.
I need to find all the lakes in a polygon bounded region using the NDWI index for water bodies, which are at a height of more than 1500m. Then display the changes in the area of lake's surface water starting from the year 1984 till 2018 on a 2-year interval in a table like structure in Google Earth Engine. I have used Landsat 5 and 7 data.
I have created the following code:
Earth Engine Code
Now I need to display the results in the polygon marked region in a table sort of structure in the following format:-
Rows - (Lake 1, Lake 2, Lake 3... Lake n)
Columns - (Surface Area in 1984, Surface Area in 1986, ....2018)
How should I go about doing it?
I answer this question in regard of the code posted in the comments, hopefully the question is updated with the code posted in the comments.
Filtering: ok.
Just a comment, I wouldn't name an image collection variable with name img, it's just confusing to me, but variables names are up to you.
var mf = ee.Filter.calendarRange(10, 12, 'month');
var img1 = ee.ImageCollection(l5
.filterDate('1984-01-01','1999-12-31')
.filterBounds(roi)
.filter(mf));
var img2 = ee.ImageCollection(l7
.filterDate('2000-01-01','2018-12-31')
.filterBounds(roi)
.filter(mf));
add NDWI: This is your code:
var addNDWI = function(image){
var ndwi = image.normalizedDifference(['B2', 'B4']).rename('NDWI');
var ndwiMask = ndwi.gte(0.3);
return image.addBands(ndwi);
};
var image1 = img1.map(addNDWI);
var image2 = img2.map(addNDWI);
you are not saving ndwiMask, so you won't be able to use it outside of this function. Again, I wouldn't name them image as they are not images but image collections.
elevation mask: you have to select the elevation band:
var elevMask = elevation.select('elevation').gt(1500)
This mask image will have ones where elevation is greater than 1500 and zeros where not.
applying masks: in this part you have to remember that Earth Engine uses functional programming, so objects are not mutable, this means that you cannot update the state of an object using a method, you have to catch the output of the method you are calling. Here you need ndwi mask, so you have to compute it with NDWI band.
var mask = function(image){
var ndwiMask = image.select('NDWI').gt(0.3)
var ndwi_masked = image.updateMask(ndwiMask);
return ndwi_masked.updateMask(elevMask);
};
var maskedImg = image1.map(mask); // ImageCollection!
var maskedImg2 = image2.map(mask); // ImageCollection!
Visualizing: As the results are ImageCollection, when you add it to the map EE makes a mosaic and that is what you would see. Keep that in mind for further processing.
var ndwiViz = {bands: ['NDWI'], min: 0.5, max: 1, palette: ['00FFFF', '0000FF']};
Map.addLayer(maskedImg, ndwiViz, 'Landsat 5 masked collection');

How to calculate location’s long/lat based on its bbox coordinates

please could anyone help?
I need to use a map.toFly() method to interpolate between 2 locations.
According to the Mapbox documentation, I need to pass in an object describing the destination I want to fly to. The object has to have a center property holding an array with centre Long/lat coordinates of the destination I need to be taken to.
https://docs.mapbox.com/mapbox-gl-js/example/flyto/
My problem with implementing the method is that I only have bounding box coordinates of the 2 locations between which I need to interpolate . I can’t do something like this:
map.flyTo(bbox)
Does anyone know how to obtain
centre Long/lat coordinates of each location based on their bbox coordinates?
Assuming you have 2 LngLatBounds objects you can call the getCenter() method.
var point1 = bounds1.getCenter();
var point2 = bounds2.getCenter();
where both bounds1 and bounds2 are objects of the type LngLatBounds.
Check:
https://docs.mapbox.com/mapbox-gl-js/api/#lnglatbounds#getcenter
Edit: for the values you gave in your comment it would be for the first bounds:
var sw1 = new mapboxgl.LngLat(110.2672863, -7.1144639);
var ne1 = new mapboxgl.LngLat(110.5088836, -6.9319917);
var bounds1 = new mapboxgl.LngLatBounds(sw1, ne1);
Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude).

How to set correct image dimensions by LatLngBounds using ImageOverlay?

I want to use ImageOverlays as markers, because I want the images to scale with zoom. Markers icons always resize to keep their size the same when you zoom.
My problem is that I can't figure out how to transform pixels to cords, so my image isn't stretched.
For instance, I decided my south-west LatLng to be [50, 50]. My image dimensions are 24px/24px.
How do I calculate the north-east LatLng based on the image pixels?
You are probably looking for map conversion methods.
In particular, you could use:
latLngToContainerPoint: Given a geographical coordinate, returns the corresponding pixel coordinate relative to the map container.
containerPointToLatLng: Given a pixel coordinate relative to the map container, returns the corresponding geographical coordinate (for the current zoom level).
// 1) Convert LatLng into container pixel position.
var originPoint = map.latLngToContainerPoint(originLatLng);
// 2) Add the image pixel dimensions.
// Positive x to go right (East).
// Negative y to go up (North).
var nextCornerPoint = originPoint.add({x: 24, y: -24});
// 3) Convert back into LatLng.
var nextCornerLatLng = map.containerPointToLatLng(nextCornerPoint);
var imageOverlay = L.imageOverlay(
'path/to/image',
[originLatLng, nextCornerLatLng]
).addTo(map);
Demo: http://playground-leaflet.rhcloud.com/tehi/1/edit?html,output