Select to view content in your preferred language

Panning around the world - geometry contains() test fails

480
3
09-06-2023 09:38 AM
JonathanTiu
Emerging Contributor

Using the sketchviewmodel i have drawn a graphic which acts like a polygon filter on the map.

 

 JonathanTiu_2-1694017947815.png

 

Anyways, i have added logic such that clicking inside the polygon pops up a custom toolbar etc.

To do all this, my code is something like this:

mapView.hitTest(clickCoordinates).then((response: any) => {

     if (response.results.length === 0) {
         const polygonFilter = getPolygonFilterGraphic(layer);

          // check if the click coordinates is inside the polygon filter
           const point = new esri.Point({

                    x: event.mapPoint.x, y: event.mapPoint.y,  spatialReference: esri.SpatialReference.WebMercator

           );
            if (polygonFilter && polygonFilter.geometry.contains(point)) {


                    // pop up the toolbar
               }

 

This works fine except in the case where i pan around the world. so in my screenshot above if i pan around the world and arrive at this polygon filter over japan again, if i click inside it, the mapPoint is never inside the polygonFilter.geometry  (ie. the contains() predicate always fails.)

I suspect it has to do with the mapPoint's x coordinate being outside the current extent xmin and xmax. do i need to be normalizing the mapPoint or the polygonFilter.geometry or both? and if so, how do i normalize it? Any help would be appreciated thanks!

 

 

 

 

0 Kudos
3 Replies
JoelBennett
MVP Regular Contributor

If your polygon is always a rectangle, then the issue is straightforward:

var extents = polygonFilter.geometry.extent.clone().normalize();
var nPoint = point.clone().normalize();

for (var x = 0; x < extents.length; x++) {
	if (extents[x].intersects(nPoint)) {
		//pop up the toolbar

		break;
	}
}

 

0 Kudos
JonathanTiu
Emerging Contributor

It won't always be a rectangle. we allow freeform filter like this. 

I see, you're normalizing the extent of the polygon filter's geometry.  does your approach not work for arbitrary shapes? i guess the extent is a rectangle...

JonathanTiu_0-1694021944427.png

 

0 Kudos
JoelBennett
MVP Regular Contributor

If your polygon won't cross the international dateline, then you can normalize it on the client-side by rebuilding it from normalized points.  If it could could cross it, then perhaps the recommended solution for normalizing the polygon would be to use normalizeUtils.normalizeCentralMeridian.  Whatever method you choose, I recommend you normalize the polygon before adding it to your GraphicsLayer.

Anyhow, assuming the polygon is normalized, then it would just be a matter of:

if (polygonFilter && polygonFilter.geometry.contains(point.clone().normalize())) {
	// pop up the toolbar
}