What is the best way to find a point or midpoint for a highlighted polyline from the 'geometry' or 'feature' of the component ?

4093
5
07-26-2016 09:12 AM
MaryAnnChiramattel
New Contributor

I have a scenario I am working on where when I click the sidebar with results, I need to open a popup and highlight the graphic of the selected result from the sidebar.

Although the graphic is always highlighted correctly for the polyline, the popup is not always consistently pointing to the polyline. Most of the time the popup points few inches away or in some case really far away from the highlighted graphic. Since the user is not directly clicking on the map, but on the sidebar, I need to explicitly pass the location for the popUp.

What is the best way to figure out the location of the polyLine for its popUp ?

Currently I am using the following to find the location for polyline. But as you can see in the screenshot, the popUp is displayed away from the polyline.

mapView.popup.open ({

                location: selectedResult.feature.geometry.extent.center,

                features: [selectedResult.feature]

            });

I am able to correctly point the popUp for point : selectedResult.feature.geometry and for a

polygon : selectedResult.feature.geometry.centroid, but for the polyLine it is not working correctly.

5 Replies
JordanKing3
New Contributor III

Not sure that there is really an easy way to do this. You could continue to do what you're already doing, but instead of snapping the popup box to the selectedResult.feature.geometry.extent.center, you could take that extent center, then pass it in to geometryEngine.nearestCoordinate() or geometryEngine.nearestVertex() to get the closest coordinate or vertex on the polyline. Then you snap the popup to the resulting geometry of the method.

But, its still probably not going to get the center of the polyline, because the extent center for the polyline can be a long way away from the polyline depending on its shape. Here's a horrible example from MS Paint!

If the red line is your polyline, then the extent of that polyline is essentially the box surrounding it. Therefore, the extent center would be the black dot, which is nowhere near the line.

Another method could be to find the middle index for the polylines paths property and try snapping to that. But again, that is all dependent on the paths and if you have a straight line polyline with only two paths (start and end) then you will have no middle to snap too.

FC_Basson
MVP Regular Contributor

You could use the middle vertex of the polyline path array:

var mid = parseInt( selectedResult.feature.geometry.paths[0].length / 2);
mapView.popup.open ({
   location: selectedResult.feature.geometry.paths[0][mid],
   features: [selectedResult.feature]
});
YousefQuran
Occasional Contributor

I was thinking on the same page as you ...

MaryAnnChiramattel
New Contributor

Thank you for the explanations, I was able to resolve the issue by following the above pattern :

I am pasting the exact pattern I wrote

For opening a  polyline popup, I needed to fill out the x & y components of  geometry, which I can retrieve using the following:

                       var mid: number = selectedResult.geometry.paths[0].length / 2;

                selectedResult.feature.geometry.x = selectedResult.feature.geometry.paths[0][mid][0];

                selectedResult.feature.geometry.y = selectedResult.feature.geometry.paths[0][mid][1];

After assigning x & y values popup.Open worked perfectly.

self.mapView.popup.open({

                location:  selectedResult.feature.geometry,

                features: [selectedResult.feature],

            });

LiamWelter-Reed
New Contributor III

To account for multi-line features, you should use flat() to flatten the array.

To find the true middle vertex, using Math.round() would be better since it actually gets the center as parseInt() only turns numbers into ints. For example, if my line has 5 vertices, parseInt() would return 2 as the mid point, when Math.round() would return 3 which is not the mathematical middle, but is the middle as far as lines are concerned.

 

var combinedLine = new Polyline({
 paths:selectedResult.feature.geometry.paths.flat(),
 spatialReference:selectedResult.feature.geometry.spatialReference
});
var midIndex = Math.round(combinedLine.paths.length / 2);
var midPoint = new Point({
 x:combinedLine.paths[midIndex][0],
 y:combinedLine.paths[midIndex][1],
 spatialReference:combinedLine.spatialReference
});

mapView.popup.open ({

   location: midPoint,

   features: [selectedResult.feature]

});

 

0 Kudos