Calculating the size of area

Back
Tags:
Drawing API
Math
Example of calculating the size of area.
Usage instructions:
Add this script to map GameObject and start the scene.
Hold Left Shift and click on the map to add a point.
Hold Control to move the points.
Size of area will be displayed in the console.
CalcAreaExample.cs
/*         INFINITY CODE         */
/*   https://infinity-code.com   */

using System;
using System.Collections.Generic;
using System.Linq;
using OnlineMaps;
using UnityEngine;

namespace OnlineMapsExamples
{
    /// <summary>
    /// Example of calculating the size of area.
    /// </summary>
    [AddComponentMenu(Utils.ExampleMenuPath + "CalcAreaExample")]
    public class CalcAreaExample : MonoBehaviour
    {
        /// <summary>
        /// Reference to the map. If not specified, the current instance will be used.
        /// </summary>
        public Map map;
        
        /// <summary>
        /// Texture of marker
        /// </summary>
        public Texture2D markerTexture;

        /// <summary>
        /// Line width.
        /// </summary>
        public float borderWidth = 1;
        
        private float _borderWidth;
        private bool changed = false;
        private ControlBase control;
        private DrawingElementManager drawingElementManager;
        private List<Marker2D> markers = new List<Marker2D>();
        private Marker2DManager markerManager;
        private List<GeoPoint> markerPositions = new List<GeoPoint>();
        private Polygon polygon;
        
        public void Clear()
        {
            if (polygon != null)
            {
                drawingElementManager.Remove(polygon);
                polygon = null;
            }

            foreach (Marker2D marker in markers) markerManager.Remove(marker);
            markers.Clear();

            markerPositions.Clear();
            changed = true;
        }

        private void CheckMarkerPositions()
        {
            // Check the position of each marker.
            for (int i = 0; i < markers.Count; i++)
            {
                if (markerPositions[i] != markers[i].location)
                {
                    // If the position marker changed, then change the value in markerPositions. 
                    // In the polygon value changes automatically.
                    markerPositions[i] = markers[i].location;
                    changed = true;
                }
            }
        }

        private void OnMapPress()
        {
            if (!InputManager.GetKey(KeyCode.LeftShift)) return;
            
            // Get the geographical coordinates of the cursor.
            GeoPoint cursorLocation = control.ScreenToLocation();

            // Create a new marker at the specified coordinates.
            Marker2D marker = markerManager.Create(cursorLocation, markerTexture, "Marker " + (markerManager.count + 1));

            // Save marker and coordinates.
            markerPositions.Add(cursorLocation);
            markers.Add(marker);

            // Mark that markers changed.
            changed = true;
        }

        private void Start()
        {
            // If map is not specified, use the current instance.
            if (!map && !(map = Map.instance))
            {
                Debug.LogError("Map not found");
                return;
            }
            
            // Get references to the control, drawingElementManager and markerManager.
            control = map.control;
            drawingElementManager = control.drawingElementManager;
            markerManager = control.marker2DManager;

            _borderWidth = borderWidth;
            
            control.OnPress += OnMapPress;
        }

        private void Update()
        {
            if (Math.Abs(_borderWidth - borderWidth) > float.Epsilon)
            {
                _borderWidth = borderWidth;
                if (polygon != null)
                {
                    polygon.borderWidth = borderWidth;
                    map.Redraw();
                }
            }

            // Check the position of the markers.
            CheckMarkerPositions();

            // If nothing happens, then return.
            if (!changed) return;
            changed = false;

            // If the number of points is less than 3, then return.
            if (markers.Count < 3)
            {
                map.Redraw();
                return;
            }

            // If the polygon is not created, then create.
            if (polygon == null)
            {
                // For points, reference to markerPositions. 
                polygon = new Polygon(markerPositions, Color.black, borderWidth, new Color(1, 1, 1, 0.3f));

                // Add an element to the map.
                drawingElementManager.Add(polygon);
            }
            else
            {
                polygon.SetPoints(markerPositions);
            }

            // Calculates area of the polygon.
            // Important: this algorithm works correctly only if the lines do not intersect.
            double area = 0;

            // Triangulate points.
            int[] indexes = Geometry.Triangulate(markerPositions).ToArray();

            // Calculate the area of each triangle.
            for (int i = 0; i < indexes.Length / 3; i++)
            {
                // Get the points of the triangle.
                GeoPoint p1 = markerPositions[indexes[i * 3]];
                GeoPoint p2 = markerPositions[indexes[i * 3 + 1]];
                GeoPoint p3 = markerPositions[indexes[i * 3 + 2]];

                // Calculate the distance between points.
                double d1 = p1.Distance(p2);
                double d2 = p2.Distance(p3);
                double d3 = p3.Distance(p1);

                // Calculate the area.
                double p = (d1 + d2 + d3) / 2;
                area += Math.Sqrt(p * (p - d1) * (p - d2) * (p - d3));
            }

            Debug.Log("Area: " + area + " km^2");

            map.Redraw();
        }
    }
}