ThinkGeo.com    |     Documentation    |     Premium Support

Required Grid on Map

Dear All,


My project requirement is, display a grid in selected area.


Suppose user select a rectanle area, where they want to create grid, here the distance of grid line will based on user, means he will give input for grid distance like 1 KM or 2 KM.


Regards


Sanjay



Sanjay, 
  
 Thanks for your post and question. 
  
 I am sorry to say that we do not have existing APIs to implement this, while I think we can accomplish this by writing our own logic even though it seems a bit complex. 
  
 Firstly we have to make sure the logic to generate the grid, which is most important. Let us say the grid distance is 2KM, while the width of the rectangle is 14.8KM, how you want the grid generated? I suppose we can generate the grid from the left of the Rectangle or the center of it. Please try the following way to see if it works: 
 1)When a rectangle is created, get the width and height of the rectangle. 
 2)Calculate how many grids will be generated to fill the rectangle. 
 3)Generate that grid into line shapes and display them into an ImemoryFeatureLayer. 
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 
  


Yale, 



Thanks for guideline. 



I have done something like: 



1. I have added a rectangular box, 

2. Calculated the width and height of box. 

3. Devide the width and height with value which provided by user. 

4. Here I chaked reminder value, if present then 1 added into result. 

5. Now, I have to calculate the new lat and long with final result 

Eq: 

featureBoundingBox.UpperLeftPoint.X=77.2921 

featureBoundingBox.UpperLeftPoint.Y=29.8933 

featureBoundingBox.UpperRightPoint.X=77.3760 

featureBoundingBox.UpperRightPoint.Y=29.8933 



and user input is 500 Meter then 



'Calculate width of Bounding Box 

Dim Boxwidth As Integer = DecimalDegreesHelper.GetDistanceFromDecimalDegrees(featureBoundingBox.UpperLeftPoint.X, featureBoundingBox.UpperLeftPoint.Y, featureBoundingBox.UpperRightPoint.X, featureBoundingBox.UpperRightPoint.Y, curMapUnit) 

'Calculate Height of Bounding Box 

Dim BoxHeight As Integer = DecimalDegreesHelper.GetDistanceFromDecimalDegrees(featureBoundingBox.UpperLeftPoint.X, featureBoundingBox.UpperLeftPoint.Y, featureBoundingBox.LowerLeftPoint.X, featureBoundingBox.LowerLeftPoint.Y, curMapUnit) 

Dim ActWidth As Integer = Boxwidth \ Val(txtDistance.Text) 

Dim ActHeight As Integer = BoxHeight \ Val(txtDistance.Text) 

Dim ExtraWidth As Integer = Boxwidth Mod Val(txtDistance.Text) 

Dim ExtraHeight As Integer = BoxHeight Mod Val(txtDistance.Text) 



If ExtraWidth > 0 Then 

ActWidth = ActWidth + 1 

End If 

If ExtraHeight > 0 Then 

ActHeight = ActHeight + 1 

End If 



Now my requirement is to find new lat, long point from 

UpperRightPoint.X = UpperLeftPoint.X + ACTWidth 'Something like that 

UpperRightPoint.Y = UpperLeftPoint.Y + ACTHeight 'Something like that 



So, that box can be made with equall distance 



Regards 

Sanjay 

 



Sanjay, 
  
 Thanks for your post and sharing, I reviewed the code snippet you provided, and I do not see any issues. 
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 


Yale, 
 Actually my requirement is, how to add distance into a particular lat long to find a new lat long on that distance. 
 Suppose- 
 Lat = 77.2921  
 Long = 29.8933  
 I want to find a new lat long with distance of 500 mrters on above lat long. 
 How we do that. 
  
 Regards 
 Sanjay

Sanjay,


 I want to point out that there is a Code Community sample Numbered Grid wiki.thinkgeo.com/wiki/Map_Suite_De...es_Samples. It shows how to construct grids with cells of a certain size on a map in decimal degrees. I think that this is going to be some help for you.



Sanjay,


 To respond more specifically to your last question, see the code below to find a point in longitude and latitude from a given point at a certain distance and certain angle in degress. (0 = to the North, 90 = to the East, 180 = to the South etc)


 Also, I am suspicious that you have Longitude and Latitude mixed up. Lat = 77.2921, Long = 29.8933 is somewhere in the Arctic Ocean. Lat = 29.8933, Long = 77.2921 is somewhere in Northern India.


 



    double Long = 29.8933;
    double Lat = 77.2921;

    PointShape pointShape1 = new PointShape(Long, Lat);

    PointShape pointShape2 = (PointShape)pointShape1.CloneDeep();
    pointShape2.TranslateByDegree(500, 90, GeographyUnit.DecimalDegree, DistanceUnit.Meter);


Dear Val, 
  
 I have already gone through Numbered Grid, and I have not problem to make grid, but concern is grid cell should be square. For this I have written code like this: 
  
 Dim UpperLeftX As Double = 77.2921 
 Dim UpperLeftY As Double = 29.8933 
 Dim Distance as Double = 500 
 'Starting Point 
 Dim PointShape1 As PointShape = New PointShape(UpperLeftX, UpperLeftY) 
 'Point Located on distance (TotWidth) in East (90 degree) location from Point1 
 Dim PointShape2 As PointShape = DirectCast(PointShape1.CloneDeep, PointShape) 
 PointShape2.TranslateByDegree(Distance, 90, GeographyUnit.DecimalDegree, DistanceUnit.Meter) 
 'Point Located on distance (TotHeight) in South (180 degree) location from Point2 
 Dim PointShape3 As PointShape = DirectCast(PointShape2.CloneDeep, PointShape) 
 PointShape3.TranslateByDegree(Distance, 180, GeographyUnit.DecimalDegree, DistanceUnit.Meter) 
 'Create Rectangle Shape based on Point1 and Point3 
 Dim returnCell As New RectangleShape(PointShape1, PointShape3) 
  
 Now, my result should be in square, because I have added same distance in Width and Height. But If you see result more specifically, it is not same. 
 Could you guide regarding my concern 
 Regards 
 Sanjay

Sanjay,


 You are right that you are going to get a different distance each time you use TranslateByDegree using the GeographyUnit DecimalDegrees. This is due to the nature of a degree of longitude decreasing as the longitude increases. See en.wikipedia.org/wiki/Latitude#Degree_length for more info.


 So, due to this reality of varying degree/distance length, you need to pick a reference point you are going to use to find the standard degree difference to build your entire grid. I would choose a reference point in the center of the grid. See code below:


 



//Reference location. We will calculate the decimal degrees difference at this location for 500 meters
//and use that longitude difference to buld the rest of the grid so that all the cells are square.
double Long = 77.2921;
double Lat = 77.8933;

PointShape pointShape1 = new PointShape(Long, Lat);

PointShape pointShape2 = (PointShape)pointShape1.CloneDeep();
//We place the pointShape2 500 meters straight east from the reference point.
pointShape2.TranslateByDegree(500, 90, GeographyUnit.DecimalDegree, DistanceUnit.Meter);

//This is the size of the cell to build your entire grid.
double cellSize = pointShape2.X - pointShape1.X;


val, 



I have done calculation as per your suggestion like 



dim width as double=pointShape2.X - pointShape1.X 

dim Height as double = pointShape2.Y - pointShape3.Y 

dim diff as double = width - Height ' it gives the difference 



Dim GridCellWidth as double = width 

Dim GridCellHeight as double = width - diff 



It gives the same distance in width and height and grid designed in square. And the problem is solved. 

But how we adjust the value in ring. For Example 

Dim Long as double = 77.2921 

Dim Lat as double = 77.8933 

Now I want to create ring of 500 meter at above point. I have created ring. The ring touch the grid cell in width direction and it seems Ok, but it crosses the grid line in height direction, which is not ok. I have used following statement to plot ring


 


Dim RingShape As EllipseShape = New EllipseShape(New PointShape(Long, Lat), 0.5, 0.5)

How we can solve this, please guide 

Regards 

Sanjay 

 



Dear Val,  
  
 I am waiting for my reply. 
  
 As I have said, when I am plotting Ring on specific point, the radius is not equal in all direction. I am plotting ring of 500 meter. Please guide me. 
 Dim Long as double = 77.2921  
 Dim Lat as double = 77.8933  
 Dim RingShape As EllipseShape = New EllipseShape(New PointShape(Long, Lat), 0.5, 0.5) 
 How we can solve this, please guide  
 Regards  
 Sanjay  


Hi Sanjay,
 
The grid should not be a square because of the projection distortion. I think you should modify the algorithm which is used to generate grids. Here we provide some code snippet for your reference.
int gridSize = 5;
PointShape[,] points = new PointShape[gridSize, gridSize];
PointShape p1 = new PointShape(0, 70);
points[0, 0] = p1;
layer.InternalFeatures.Add(p1.GetFeature());
for (int i = 1; i < gridSize; i++)
{
    PointShape p = (PointShape)p1.CloneDeep();
    p.TranslateByDegree(100 * i, 360, Map1.MapUnit, DistanceUnit.Kilometer);
    layer.InternalFeatures.Add(p.GetFeature());
    points[0, i] = p;
}

for (int i = 0; i < gridSize; i++)
{
    PointShape point = points[0, i];
    for (int j = 1; j < gridSize; j++)
    {
        PointShape p = (PointShape)point.CloneDeep();
        p.TranslateByDegree(100 * j, 270, Map1.MapUnit, DistanceUnit.Kilometer);
        layer.InternalFeatures.Add(p.GetFeature());
        points[j, i] = p;
    }
}

for (int i = 0; i < gridSize; i++)
{
    LineShape line = new LineShape();
    LineShape line2 = new LineShape();
    for (int j = 0; j < gridSize; j++)
    {
        PointShape point = points[i, j];
        line.Vertices.Add(new Vertex(point.X, point.Y));
        PointShape point2 = points[j, i];
        line2.Vertices.Add(new Vertex(point2.X, point2.Y));
    }
    layer.InternalFeatures.Add(line.GetFeature());
    layer.InternalFeatures.Add(line2.GetFeature());
}

EllipseShape ellipse = new EllipseShape(points[2, 2], 100, 100, Map1.MapUnit, DistanceUnit.Kilometer);
layer.InternalFeatures.Add(ellipse.GetFeature());

The output is below (the shapes in blue should be squares in real world.):

 
Regards,
 
Ivan

Hi Ivan, 



Thanks for Reply and sharing information. 



Actually we are in Telecom Field and doing site survey for our customers. So the grid which I have plotted that is not a lat long grid. That is basically ditance grid, which is useful to our customer to see how many kilometers, survey has done and the same purpose circle is required.


Only input is availavle about the cell size of grid. Eq- The distance of cell line (like 500 mtr), We don't know how much cell in grid. We simply select an area by mouse and given input of distance and creating grid based on distance and selected area. 


So, if customers draw a grid on survey data, they should know the facts which is visible on map. The same in Circle case, if a circle plot on a center point of grid, as you shown above, the circle should touch the point as you shown. 



I will try to plot circle as you guided and then confirm you about my status. 



Regards 

Sanjay



Hi Sanjay, 
  
 I’ll keep an eye on your feedback, hope everything goes well. 
  
 Regards, 
  
 Ivan

Hi Ivan, 
  
 Now my grid is OK and also the circle plotted on grid looks ok. I also hoping it will work for me. Lets I am also waiting for my users feedback.  
  
 One thing I want to do on grid layer. After plotting the grid I want to display some text on grid layer which location could be the corner of grid, like 
  
 1 Box = 500 Meter 
  
 Is it possible. 
  
 Regards 
 Sanjay

Hi Sanjay, 
  
 I’m sorry that I can’t fully understand your requirement. Do you need to display text for each grid, or you just want to display a single text for the Grid Layer? 
  
 Regards, 
  
 Ivan

Hi Ivan, 
  
 Thanks for Reply 
  
 I want to display just a single text for the Grid Layer. If the Text location is grid corner it will better for me. The Text is  
  
 1 Box = 500 Meter 
  
 Regards 
 Sanjay 
  


Sanjay,


Try following code snippet to create the layer and I attached the result for it too.
 
 
            InMemoryFeatureLayer layer = new InMemoryFeatureLayer();
            layer.Open();
            layer.Columns.Add(new FeatureSourceColumn("GridName","string",20));
            layer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway1;
            layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
            layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City1;
            layer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City1("GridName");
            layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            int gridSize = 5;
            PointShape[,] points = new PointShape[gridSize, gridSize];
            PointShape p1 = new PointShape(0, 70);
            points[0, 0] = p1;
 
            Feature feature = p1.GetFeature();
            //feature.ColumnValues.Add("GridName", "1 Box = 500 Meter");
 
            layer.InternalFeatures.Add(feature);
            for (int i = 1; i < gridSize; i++)
            {
               PointShape p = (PointShape)p1.CloneDeep();
                p.TranslateByDegree(100 * i, 360, winformsMap1.MapUnit, DistanceUnit.Kilometer);
                layer.InternalFeatures.Add(p.GetFeature());
                points[0, i] = p;
            }
 
            for (int i = 0; i < gridSize; i++)
            {
                PointShape point = points[0, i];
                for (int j = 1; j < gridSize; j++)
                {
                    PointShape p = (PointShape)point.CloneDeep();
                    p.TranslateByDegree(100 * j, 270, winformsMap1.MapUnit, DistanceUnit.Kilometer);
 
 
                    Feature feature1 = p.GetFeature();
 
                    if((j == gridSize -1) && ( i == gridSize -1))
                    {
                    feature1.ColumnValues.Add("GridName", "1 Box = 500 Meter");
                    }
 
                    layer.InternalFeatures.Add(feature1);
 
                    points[j, i] = p;
                }
            }
 
            for (int i = 0; i < gridSize; i++)
            {
                LineShape line = new LineShape();
                LineShape line2 = new LineShape();
                for (int j = 0; j < gridSize; j++)
                {
                    PointShape point = points[i, j];
                    line.Vertices.Add(new Vertex(point.X, point.Y));
                    PointShape point2 = points[j, i];
                    line2.Vertices.Add(new Vertex(point2.X, point2.Y));
                }
                layer.InternalFeatures.Add(line.GetFeature());
                layer.InternalFeatures.Add(line2.GetFeature());
            }
 
            EllipseShape ellipse = new EllipseShape(points[2, 2], 100, 100, winformsMap1.MapUnit, DistanceUnit.Kilometer);
            layer.InternalFeatures.Add(ellipse.GetFeature());
 
 
Any more questions please feel free to let me know
 
Thanks.
 
Yale

Sanjay,


 
I am sorry I missed the attachment, I am trying to attach again.
 

 
Thanks
 
Yale

Hi Yale, 
  
 Thanks for reply.  
 Actually when text display in box is crossing in two box or also depends the zoom level. It will be better if text placed at above line of box. I tried to plece the text at upper left corner wth help fo following code 
  
 CustomTextStyle.PointPlacement = PointPlacement.UpperLeft 
  
 But its not working. So it will be better if text placed at above the line. Please guide me. 
 Regards