How to collect all possible coordinates present inside a polygon area

Basically I want to calculate the location which has max height terrain of the selected area. Area is selecting by drawing a polygon.

I understand that we can get actual terrain height with the help of Cesium.sampleTerrainMostDetailed

So to pass coordinates array sampleTerrainMostDetailed, first I need to calculate all the possible coordinates present inside the drawn polygon.

var viewer = new Cesium.Viewer('cesiumContainer');

var bluePolygon = viewer.entities.add({
    name : 'Blue polygon',
    polygon : {
        hierarchy : {
            positions : Cesium.Cartesian3.fromDegreesArray([-99.0, 30.0,
                                                            -85.0, 30.0,
                                                            -85.0, 40.0,
                                                            -99.0, 40.0]),
           
        },
        material : Cesium.Color.BLUE.withAlpha(0.5),
        height : 0,
        outline : true // height is required for outline to display
    }
});
console.log(JSON.stringify(bluePolygon.polygon.hierarchy.valueOf()));
viewer.zoomTo(viewer.entities);

In short, I want to collect all the possible coordinates which are present inside a polygon to pass them in sampleTerrainMostDetail function to know which coordinate has max height.

Sandcastle link

Regards,

  • Jacky

Hi, Jacky.
Take a look to the pointGrid method in the Turf library.
We use it in a project I work to solve the similar issues.

1 Like

Thank you Sooo much @Olga_Aptekar for giving me a hint. I’m new on turf, So could you please try to tell me how can I use turf in my sandcastle code to get all coordinates present inside the polygon? Will it work if polygon shape is zigzag?

  • Jacky

@Jacky, yes, it will work for any shape of polygon.

I’m not sure that it is possible to use a side library in the Cesium Sandcastle.
But you can use Turf playground to see how it works.

Example for Turf playground:

const map = L.map("map").setView([42.32481709325035, -72.37353086471558], 20);

L.tileLayer('https://stamen-tiles.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);


const polygon = turf.polygon([
      [
        [-72.37353086471558, 42.32481709325035],
        [-72.3738956451416, 42.324594989789134],
        [-72.3735523223877, 42.324436343979656],
        [-72.37387418746948, 42.32430942704402],
        [-72.37363815307616, 42.32405559240466],
        [-72.37391710281372, 42.32388108049599],
        [-72.37363815307616, 42.32367483852534],
        [-72.37352013587952, 42.32375416244021],
        [-72.37370252609253, 42.32385728338004],
        [-72.37343430519104, 42.32408732179058],
        [-72.37361669540404, 42.32429356240905],
        [-72.37331628799438, 42.324428411678674],
        [-72.373605966568, 42.3246108543481],
        [-72.37338066101074, 42.32473777067564],
        [-72.37353086471558, 42.32481709325035]
      ]
    ]);

L.geoJson(polygon).addTo(map);

// Takes a set of features, calculates the bbox of all input features, and returns a bounding box.
// BBox - bbox extent in minX, minY, maxX, maxY order
// http://turfjs.org/docs/#bbox
const bbox = turf.bbox(polygon);
const cellSideMeter = 1.0;
const options = {
	units: 'meters',
  mask: polygon
};

// Creates a Point grid from a bounding box, FeatureCollection or Feature.
// FeatureCollection <Point> - grid of points
// http://turfjs.org/docs/#pointGrid
const pointGrid = turf.pointGrid(bbox, cellSideMeter, options);
const pointGridCoordinates = pointGrid.features.map(f => f.geometry.coordinates);

console.log(pointGridCoordinates);

After these calculations you may copy resulted pointGrid coordinates from a console to Cesium Sandcastle code, like here

1 Like

That’s amazing. Thank you so much @Olga_Aptekar for the example code you have shared. You saved me :heart_eyes:

I’m glad to hear that :slight_smile:
Good luck, @Jacky

@Olga_Aptekar

You are a rockstar! Thank you for taking a look at this thread :pray:

-Sam

1 Like

Sorry to resurrect this ancient thread, but I am having difficulty using Turf and Cesium together.

I have one set of coordinates that I am using to create a Cesium polygon entity as well as a Turf polygon. I render the Cesium polygon, then use Turf to create a pointGrid using the Turf polygon as a mask.

When I render each point from the Turf pointGrid using Cesium, the grid looks mostly fine–unless the longitude between two points is great. It looks like Turf is using a different projection, perhaps. I wish I could provide an actual image, but I develop on an air-gapped system. I’ve attached an image below that shows how the Cesium renders the polygon (in red) correctly, and the blue line represents the top edge of the Turf pointGrid, rendering with a curve.

The polygon data has two functions, one which returns an array for Cesium to use

{cesiumPoints : [long, lat, long, lat, long, lat]}

and one which returns an array to be converted to a Turf polygon

{turfPoints: [[[long,lat],[long,lat],[long,lat]]]}

The Cesium entity is created by making a Cesium.PolygonHierarchy from a Cartesian3 that’s been generated from the degrees array.

For the pointGrid, I create a Turf grid, then iterate through the points, rendering each point using Cesium.

let polygon = turf.polygon(turfPoints);
let cellSide = 100;
let options = {mask:polygon};
let pointsGrid = turf.pointGrid([bbox],cellSide,options);
pointsGrid.features.forEach(pt=>{
    addPoint(pt.geometry.coordinates[0]. pt.geometry.coordinates[1]);
});

Where addPoint(long,lat) simply creates a Cartesian3 from degrees and renders the point.

How are you resolving the different types of projection that Turf and Cesium seem to have? Converting the Turf polygon before I use it as a mask to either Mercator or Wgs84 was a dead end.

Hi there,

Make sure you are using the same arc type, either Rhumb or Geodesic, across both programs for an apples-to-apples comparison.