How to get sentinel hub image overlay only for the bounds of drawer polygon in React leaflet

Hello, this is mu request for getting NDVI filter for the leaflet map, it works. But now I am researching for about 2 months how get this layer only in the bounds of the drawer polygon. I don’t want to set the map bounds in the sentinel hub playground I want to be set dynamically:

This is my code for getting sentinel hub NDVI filter for the whole map:

 <WMSTileLayer
          layers="NDVI"
          format="image/jpeg"
          attribution='&copy; <a href="http://www.sentinel-hub.com/" target="_blank">Sentinel Hub</a>'
          url="https://services.sentinel-hub.com/ogc/wms/0eb749da-a491-MASKED"
          urlProcessingApi="https://services.sentinel-hub.com/ogc/wms/aeafc74a-c894-MASKED"
          maxcc="20"
          minZoom="6"
          maxZoom="16"
          preset="NDVI"
          time="2020-04-01/2020-10-08"
        />

I read this article but it doesn’t help me… please assist

https://www.sentinel-hub.com/faq/how-can-i-clip-image-specific-polygon/

Hi Alexander,

May I ask which React library you are using? React Leaflet has a WMSTileLayer component, but the props look very different (WMS parameters should be passed through params prop), so I assume you are using something else?

It also seems to me you can also leave urlProcessingApi prop out.

But assuming that the props of this component get translated to query parameters, something like this should work:

  ...
  url="https://services.sentinel-hub.com/ogc/wms/0eb749da-a491-MASKED"
  maxcc="20"
  geometry="POLYGON((-7.877244 38.546511,-7.876377 38.547818,-7.871950 38.546125,-7.872611 38.545023,-7.877244 38.546511))"
  ...

Hope it helps - if not, please specify which library the component WMSTileLayer comes from and we’ll try to come up with a better solution.

EDIT: It occured to me that you might be using an older version of React Leaflet, and indeed, the component signature matches. In that case the solution above should work because the props are passed verbatim.

Thanks what version should I use for react leaflet

I saw that i have version 2.7.0 of react-leaflet

The WMSTileLayer comes from react-leaflet:

import { TileLayer, WMSTileLayer, LayersControl } from “react-leaflet”;

when I paste geometry tag I receive this:

<ServiceException>

<![CDATA[ Error parsing GEOMETRY param! ]]>

</ServiceException>

</ServiceExceptionReport>

> geometry="POLYGON((42.696295, 23.303643,42.699295, 23.303643,42.699295, 23.313643,42.679295, 23.313643))"

The version doesn’t matter (as far as Sentinel Hub is concerned), whatever you wish is OK.

I think the problem is in the polygon definition, it should look like this:

geometry="POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643, 42.679295 23.313643))"

Note the spaces instead of commas (see WKT on wikipedia for more info).

It returns me a white layer…

<WMSTileLayer
          layers="NDVI"
          format="image/jpeg"
          attribution='&copy; <a href="http://www.sentinel-hub.com/" target="_blank">Sentinel Hub</a>'
          url="https://services.sentinel-hub.com/ogc/wms/0eb749da-<HIDDEN>"
          geometry="POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643, 42.679295 23.313643))"
          maxcc="20"
          minZoom="6"
          maxZoom="16"
          preset="NDVI"
          time="2020-04-01/2020-10-08"
        />

This polygon is hardcoded and I want to fill it with the NDVI filter of sentinel

My idea is to fill the layer only in the polygon bounds…

Can you write me an email to al.velchevv@gmail.com because I don’t know what to do…

I took the liberty of editing out the instance ID in your post, hope you don’t mind (they shouldn’t be published publicly to avoid abuse).

I think you need to fix just two things:

  • close the polygon
  • make sure you are using the correct CRS in the polygon

For closing the polygon, this should work:

geometry="POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643,42.679295 23.313643,42.696295 23.303643))"

However for the CRS, you should check which one the Leaflet is using. You can do this by clicking on the request in developer tools (which I see in the screenshot you are already using) and checking “CRS” parameter value. Geometry of the polygon must be specified in the same CRS.

You should also be careful about the version parameter. In OGC, the order of coordinates in EPSG:4326 depends on it (see here for explanation).

The matching WMS request (which works, if you put in the whole instance ID) is:

https://services.sentinel-hub.com/ogc/wms/0eb749da-<HIDDEN>?SERVICE=WMS&REQUEST=GetMap&VERSION=1.3.0&LAYERS=NDVI&MAXCC=20&WIDTH=640&HEIGHT=640&CRS=EPSG:4326
&BBOX=42.679295,23.303643,42.699295,23.313643&geometry=POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643,42.679295 23.313643,42.696295 23.303643))&time=2020-04-01/2020-10-08

(Note: I edited out my previous answer because it was wrong)

Do toy think the problem is in the

> <WMSTileLayer>

tag…

how it should works because when I paste the request you provide in the empty tab

https://services.sentinel-hub.com/ogc/wms/0eb749da-a491-48e4-80e5-
MASKED?SERVICE=WMS&REQUEST=GetMap&VERSION=1.3.0&LAYERS=NDVI&MAXCC=20&width=256&height=256
&BBOX=42.679295,23.303643,42.699295,23.313643&geometry=POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643,42.679295 23.313643,42.696295 23.303643))&time=2020-04-01/2020-10-08

I think that the params are not well passed because I need to make the call with the params in the tag

Sorry if I was not clear enough… To avoid miscommunication, I have now installed react-leaflet@2.7.0 and tried the solution myself.

What you need to do is:

  <WMSTileLayer
    version="1.3.0"
    layers="NDVI"
    format="image/png"
    crs={L.CRS.EPSG4326}
    attribution='&copy; <a href="http://www.sentinel-hub.com/" target="_blank">Sentinel Hub</a>'
    url="https://services.sentinel-hub.com/ogc/wms/0eb749da-<HIDDEN>"
    geometry="POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643, 42.679295 23.313643,42.696295 23.303643))"
    maxcc="20"
    minZoom="6"
    maxZoom="16"
    preset="NDVI"
    time="2020-04-01/2020-10-08"
    transparent="true"
  />

You might need to add an import for L:

import L from 'leaflet';

I have also added transparency as wou will probably wish to have that too.

Let me know if this works for you.

Really really really thanks a lot.

My last question is how to pass dynamically coordinates into this:

geometry="POLYGON((42.696295 23.303643,42.699295 23.303643,42.699295 23.313643, 42.679295 23.313643,42.696295 23.303643))"
    maxcc="20"

When I draw a polygon I successfully get the coordinates but how can I pass them to the geometry tag, not to be hardcoded…

Thanks thanks thanks a lot!

No problem, glad it worked! :slight_smile:

When I draw a polygon I successfully get the coordinates but how can I pass them to the geometry tag, not to be hardcoded…

I can’t really advise how to do that specifically, because it depends on the format of coordinates you have. This prop (geometry) is just a string - you just need to construct it from the coordinates you have.

This is just an example which will probably not work for you, but it gives an idea of how the code would look approximately:

  // assuming coordinates are saved like this:
  // const coords = [[42.696295, 23.303643], [42.699295, 23.303643], [42.699295, 23.313643], [42.679295, 23.313643], [42.696295, 23.303643]];

  ...
  geometry={`POLYGON((${coords.map(coord => coord.join(' ')).join(', ')}))`}
  ...

But again, this is very specific to the data you have and is not really related to Sentinel Hub.

I have the same problem but when I tried the solution you proposed, it didn’t work for me because I am using react-leaflet@4.2.1 so can you help me converting the solution to the version I got ,I tried to convert using chatgpt and also using documentation but I didn’t succeed doing it

thanks

It’s not much information, but I will try to help.

If you were already able to display data from sentinel hub without the geometry …

  • … and when you pass the geometry, the pixels around are black / some other color

    • be sure to set transparency in the evalscript for the pixels outside your geometry (docs) and to set the format for the WMSTileLayer to image/png
  • … and you get an error / the geometry is not used when you pass the geometry

    • be sure to transform your geometry to the correct WKT string and to use the same CRS for the map and the geometry

I’m preparing a demo which should help, but it’s unfortunately not finished yet.

Hope this helps.
Cheers

Thanks so much,this really helped me

Hi, I’m working on a React application where I have a button that loads the NDVI image for a selected polygon field. The API call returns the WMS link for the NDVI image. The issue arises when I include the Geometry parameter in the request. Without it, the code runs fine and returns a square BBOX, but when I add the Geometry parameter alongside the BBOX, I encounter an exception error.

Here’s the relevant portion of my code:

const getWMSImageUrl = (accessToken, bbox) => {
const bbox = ‘23.303643,42.679295,23.313643,42.699295’;
const baseUrl = https://services.sentinel-hub.com/ogc/wms/${instance_id};
const layer = “NDVI”;
const width = 512;
const height = 512;
const time = “2024-01-01/2024-01-31”;
const format = “image/png”;
const geometry = “POLYGON((42.696295 23.303643,42.699295 >23.303643,42.699295 23.313643,42.679295 23.313643,42.696295 23.303643))”;

return (
${baseUrl}?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap +
&LAYERS=${layer}&MAXCC=20&BBOX=${bbox}&WIDTH=${width} +
&HEIGHT=${height}&FORMAT=${format} +
&TIME=${time}&CRS=EPSG:4326 +
&GEOMETRY=${encodeURIComponent(geometry)} +
&SHOWLOGO=false
);
};

Additional Information:

  1. I’m not using React Leaflet; instead, I’m using @react-google-maps/api to load the map, draw polygons, and save coordinates.
  2. The code works perfectly when only the BBOX is specified, but fails with the Geometry parameter.
  3. I’ve hardcoded both the BBOX and Geometry for now.