Select to view content in your preferred language

View goTo target, looking for the best solution if there are many polygons and graphics.

2729
29
12-28-2022 03:31 AM
DimaY
by
New Contributor

At a certain user's choice, I draw the necessary polygons at the given coordinates from the given object and add them to the map in the form of graph figures. Then I want to show the selection on the map and use method GOTO.  Polygons are added in a loop.  I've already tried all sorts of ways. And zoomed in. And changed in a cycle. And after the cycle. And in the end, it's still kind of clumsy. That's not in the right place. Either too small or too large. If, for example, the United States, then it is not in the middle at all. How best to use To zoom the user on the map to the right place? Is there a better optimal solution? Has anyone encountered similar problems?

my code is something like this :

 

const map = new Map({
ground: "world-elevation",
basemap: grayBasemap
});

const view = new SceneView({
container,
map: map,
qualityProfile: "high",
zoom: 4
});

this.view.graphics.removeAll();

for (var i = 0; i < objCoordinates.length; i++) {
var coordinates = objCoordinates[0];
var polygon = new Polygon();
polygon.addRing(coordinates);

var polygonGraphic = new Graphic({
geometry: polygon,
symbol: fillSymbol
});

this.view.graphics.add(polygonGraphic);
}

this.view.goTo({
target: this.view.graphics
}).catch(this.catchAbortError);

0 Kudos
29 Replies
JoelBennett
MVP Regular Contributor

What coordinate system are these geometries using?  Is it WGS 84, Web Mercator, or something else?

0 Kudos
DimaY
by
New Contributor

I don't even know what to answer. I get json object "MultiPolygon" with a huge array of coordinates { x, y }. Where each array of set coordinates I add to a polygon.

var polygon = new Polygon();
polygon.addRing(coordinates);

And the polygon to the Graphic.
var polygonGraphic = new Graphic({
geometry: polygon,
symbol: fillSymbol
});

this.view.graphics.add(polygonGraphic);

And as a result, graphics with many polygons. Including the islands and territories around the USA and the USA itself. As you saw in the picture. But after the function GOTO,  we see the edge, and not the center of the Graphics.

 

 

0 Kudos
JoelBennett
MVP Regular Contributor

If the 'x' values of your polygons range from -180 to 180, then it's WGS 84...if they're much larger, then it's almost certainly Web Mercator.  I have a workaround in mind, but need to know which coordinate system it is.

0 Kudos
DimaY
by
New Contributor

'x' values of polygons range from -180 to 180.

0 Kudos
JoelBennett
MVP Regular Contributor

Ok, so in the case where it doesn't zoom properly, you're having the view go to an extent whose xmin is -180 and xmax is 180.  This is impossible to display on a globe, so it zooms out to show as much of the globe as it can, and centers at the center of the extent, which happens to be the Prime Meridian (where x = 0).  The solution is to detect cases that wrap around the International Dateline, and build an extent whose xmin is on the left of it, and whose xmax is on the right of it.  This means the xmax will be greater than 180, but that's ok, because the API is capable of handling wrapping.

To start with, you can remove our function from previously called "fixExtent".  Then you can add this function in its place:

function adjustExtent(extent) {
	if (extent.xmin < 0) {
		extent = extent.clone();
		extent.xmax += 360;
		extent.xmin += 360;
	}

	return extent;
}

 

Then, we change the main code to this:

var isSplit = false;
var extents = [];
var extent;

for (var i = 0; i < objCoordinates.length; i++) {
	//etc...

	extent = polygon.extent;

	if (i === 0)
		extents.push(extent.clone());
	else {
		extents.push(extent);

		if (Math.abs(extent.xmin - extents[i-1].xmax) > 90)
			isSplit = true;
	}
}

if (isSplit) {
	extent = adjustExtent(extents[0]);

	for (var x = 1; x < extents.length; x++)
		extent.union(adjustExtent(extents[x]));
} else {
	extent = extents[0];

	for (var x = 1; x < extents.length; x++)
		extent.union(extents[x]);
}

this.view.goTo(extent).catch(this.catchAbortError);

 

In the first (main) loop, we capture all the extents, and see if they're split across the dateline.  Afterwards, we loop through them again, and process them according to whether or not they're split across the dateline.  If they are, the ones the right side of the dateline are wrapped around the world once so their x values are greater than 180.  This will enable us to produce the smallest extent that crosses the dateline.

0 Kudos
DimaY
by
New Contributor

Wow! Thank you! Super! It works!  😊

But for some reason the zoom does less, instead of doing more.

0 Kudos
JoelBennett
MVP Regular Contributor

I'm not certain if you're saying it doesn't zoom out far enough, or it zooms in closer than it should.  In either case, it's possible to make the extent larger or smaller with expand.  Supplying a decimal number greater than 1 will make the extent larger; supplying a decimal number between 0 and 1 will make it smaller.

0 Kudos
DimaY
by
New Contributor

I will sum up some results of what has been done, because the top is just amazing! No wonder I opened it and no wonder you appeared here and thank you very much!   After the last change, the problematic part falls into place as it should, but the globe itself becomes smaller, that is, the zoom is smaller. That is, as you said, it does not bring closer. It just zooms out the map. All other cases and ways work fine with the old solution. Therefore, all the codes came in handy and I use them in different cases. Because if I choose one solution for all cases, then something goes wrong somewhere.

0 Kudos
DimaY
by
New Contributor

And a little remark about expand. If you want to make the map bigger, then you need to set the value less than 1. And if you reduce it, then more than 1. This is how this function works    this.view.goTo(this.extent.expand(0.5))   For example, in this case, the zoom will increase, if you set the value to 1.5, then the zoom will decrease.  

0 Kudos
DimaY
by
New Contributor

You helped a lot. Thank you very much! The topic can be closed.

0 Kudos