TheGoat
TheGoat

Reputation: 2867

Create Map Polygons from Excel data in R

I have a list of lat long coordinates each with corresponding azimuths (directions) such as:

    Site    | Cell        | Lat | Long | Azimuth (degrees) | Beamwidth
    CE0001  | CE0001U09A1 | X   | Y    |    0              |    65
    CE0001  | CE0001U09B1 | X   | Y    |    120            |    65
    CE0001  | CE0001U09C1 | X   | Y    |    240            |    65

For each unique cell, I would like to create a triangular polygon that is oriented in the direction of the azimuth for the corresponding cell with a width of 65degs and a radius of say 2km. I would like to generate shapes similar to what is shown below.

Can anyone point me in the direction as to how I could begin coding this up to loop through each entry in my file and how to generate a single google earth file that contains a polygon for each one? There are approx 9000 or so cells that require a polygon but if I can get this working for a small sample I would be very happy.

Google Earth Azimuth Example

Upvotes: 1

Views: 1480

Answers (1)

rheitzman
rheitzman

Reputation: 2297


Here is and old post I made to a forum of a script to build hexagon tiles. Some of the calls are to the GIS API but I think you can probably extracted the needed VBA code:

        .. VB script to create some hexagon tiles.
        It creates tiles of a given radius (circle around a tile), not side length. If you want side length you will need to do the math and updte the code.
        Here is the Comments from the .map file:
        Creating a drawing of hexagon tiles:
        R - radius
        Radius of circumscribed circle around tile
        a - Apothem:
        Distance from centroid perpendicular to a side
        a = R * cos(1/2 * 360/n) (n=6 for a hexagon
        A set of hexagon tiles would be a series of six sided
        "circles" centered on two point grids (1 & 2). Both grids
        would have the spacing of:
        in X --- 3R
        in Y --- 2a
        Grid 2 would be offset from grid 1 by:
        in X ---- 3R/2
        in Y ---- 2a/2
        To test script delete all objects in A then
        run the script.
        This sample was only tested with a lat/long drawing. I'm not
        sure of all the ramifications of using a projected drawing.
        To use with your data set the start point (upper left) in the script and desired radius.
        Set precision and run Normailize Topology when done to join
        the tiles.
        Code was based on the FreeStuff sample scripts ScriptRandomPoints
        and ScriptSpatialOperations.
        Please post any problems you find with this code.
        Hmmm.. the attachments option is gone? :-?
        Send me your address via email and send the .map file if you'd like.
        Here's the code:
            Sub Main
            ' test lat/long drawing
            ' ** ** delete all objects in A to test
            set drawing = Application.ActiveDocument.ComponentSet("A")
            set objects = drawing.ObjectSet
            sides = 6
            pi = 3.14159
            R = 2.5 ' radius in degrees
            interiorAngle = (360/6) * (pi / 180) ' in radians
            a = abs(R * cos(0.5 * interiorAngle)) ' apothem
            ' pick/make a start point - upper left
            Set startPoint = Application.NewPoint
            startPoint.X = -25
            startPoint.Y = 73.6602540378444
            ' grid (4x3x2)
            for i = 0 to 3
            for j = 0 to 2
            ' -- create point grid 1
            Set point = Application.NewPoint
            point.X = startPoint.X + (i * 3 * R)
            point.Y = startPoint.Y - (j * 2 * a)
            ' objects.Add Application.NewGeom(GeomPoint, point) ' centroid
            Set pointSet = Application.NewPointSet
            For k = 0 To sides -1
            Set pt = Application.NewPoint
            ' calculate angle
            angle = (k*2*Pi/sides)' - (360/sides)/2
            ' obtain point on circle
            pt.X = point.X + R*Cos(angle)
            pt.Y = point.Y + R*Sin(angle)
            pointSet.Add(pt)
            Next
            objects.Add Application.NewGeom(GeomArea, pointSet)
            ' -- create point grid 2
            Set point = Application.NewPoint
            point.X = startPoint.X + (i * 3 * R) + ((3 * R)/2)
            point.Y = startPoint.Y - (j * 2 * a) - a
            ' objects.Add Application.NewGeom(GeomPoint, point) ' centroid
            Set pointSet = Application.NewPointSet
            For k = 0 To sides -1
            Set pt = Application.NewPoint
            ' calculate angle
            angle = (k*2*Pi/sides)' - (360/sides)/2
            ' obtain point on circle
            pt.X = point.X + R*Cos(angle)
            pt.Y = point.Y + R*Sin(angle)
            pointSet.Add(pt)
            Next
            objects.Add Application.NewGeom(GeomArea, pointSet)
            next
            next
            msgbox "Done!"
            End Sub

Here's a cleaned up version that just developes one hex tile. You should be able to modify it to do what you want.

        Sub xx()
            Dim startPoint As clsPoint
            Dim Point As clsPoint
            Dim pt As clsPoint
            Dim pts As Collection
            Dim s As String

            '  lat/long (western hemisphere?)

            Dim sides, i, j, k As Integer
            Dim Pi, R, interiorAngle, A, Angle As Double

            sides = 6
            Pi = 3.14159
            R = 0.25 ' radius in degrees
            interiorAngle = (360 / 6) * (Pi / 180) ' in radians
            A = Abs(R * Cos(0.5 * interiorAngle)) ' apothem

            ' pick/make a start point - upper left
            Set startPoint = New clsPoint
            startPoint.X = -121.5
            startPoint.Y = 35.5
            s = "Longitude" & vbTab & "Latitude" & vbCrLf
            s = s & startPoint.X & vbTab & startPoint.Y & vbCrLf

            Set Point = New clsPoint
            Point.X = startPoint.X '+ (i * 3 * R)
            Point.Y = startPoint.Y '- (j * 2 * A)

            Set pts = New Collection
            For k = 0 To sides - 1
                Set pt = New clsPoint
                ' calculate angle
                Angle = (k * 2 * Pi / sides) ' - (360/sides)/2
        '        Debug.Print Angle
                ' obtain point on circle
                pt.X = Point.X + R * Cos(Angle)
                pt.Y = Point.Y + R * Sin(Angle)
                pts.Add pt
            Next

            For Each pt In pts
                 s = s & pt.X & vbTab & pt.Y & vbCrLf
            Next
            Debug.Print s
            Stop
        End Sub

clsPoint just contains:

Public X As Double
Public Y As Double

Upvotes: 1

Related Questions