I have the following:
bool AreNear(Point Old, Point Current)
{
int x1 = Convert.ToInt32(Old.X);
int x2 = Convert.ToInt32(Current.X);
int y1 = Convert.ToInt32(Old.Y);
int y2 = Convert.ToInt32(Current.Y);
if (x1 == x2) {
if (y1 == y2) {
return true;
}
}
return false;
}
I want to return true in the function if the current point is in 25 pixels radius of the old point. Can anyone tell me how to do that?
You can use the Pythagorean formula to calculate the distance between two points. In C#:
var d = Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2))
Why does this work? Have a look at the following diagram and remember that a^2 + b^2 = c^2 holds for right triangles:
Just calculate the square of the distance using Pythagoras' theorem, and compare to the square of the radius:
bool ComparePoints(Point Old, Point Current)
{
int x1 = Convert.ToInt32(Old.X);
int x2 = Convert.ToInt32(Current.X);
int y1 = Convert.ToInt32(Old.Y);
int y2 = Convert.ToInt32(Current.Y);
int dx = x1 - x2;
int dy = y1 - y2;
return (dx*dx + dy*dy) < 25*25;
}
You can use Math.Abs to get the distance:
public static bool InDistance(Point Old, Point Current, int distance)
{
int diffX = Math.Abs(Old.X - Current.X);
int diffY = Math.Abs(Old.Y - Current.Y);
return diffX <= distance && diffY <= distance;
}
use it:
bool arePointsInDistance = InDistance(new Point(100, 120), new Point(120, 99), 25);
Try using the distance formula http://www.purplemath.com/modules/distform.htm and compare the distance <=25
I have three points, for example:
Start 194 171
Right 216 131
Left 216 203
I want to get all the points within that triangle. How would I do that efficiently?
see z3nth10n's answer for better input validation
Introduction:
The general idea was to get the triangle's edges (y-Wise) for every x in it's range, and then you have all the y's that exist within the triangle for every single x, which with simple conversion turns into all points within the triangle.
You can look at it as if you cut the triangle into stripes, each being of width 1.
So for X=0, on the line between A and B, the Y is 6, and on the line between A and C, the Y is -2, so you can see that the stripe of X=0 is between -2 and 6. Therefore, you can tell that (0, -2) (0, -1) (0, 0) ... (0, 5) (0, 6) are all in the triangle. Doing that for X's between the smallest and the largest within the triangle, and you have all the points in the triangle!
Speed:
For the triangle (0, 0) (1, 8) (4, 6) - found 16 points.
Done 1,000,000 times in 3.68 seconds.
Implementation:
public IEnumerable<Point> PointsInTriangle(Point pt1, Point pt2, Point pt3)
{
if (pt1.Y == pt2.Y && pt1.Y == pt3.Y)
{
throw new ArgumentException("The given points must form a triangle.");
}
Point tmp;
if (pt2.X < pt1.X)
{
tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
if (pt3.X < pt2.X)
{
tmp = pt2;
pt2 = pt3;
pt3 = tmp;
if (pt2.X < pt1.X)
{
tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
}
var baseFunc = CreateFunc(pt1, pt3);
var line1Func = pt1.X == pt2.X ? (x => pt2.Y) : CreateFunc(pt1, pt2);
for (var x = pt1.X; x < pt2.X; x++)
{
int maxY;
int minY = GetRange(line1Func(x), baseFunc(x), out maxY);
for (var y = minY; y <= maxY; y++)
{
yield return new Point(x, y);
}
}
var line2Func = pt2.X == pt3.X ? (x => pt2.Y) : CreateFunc(pt2, pt3);
for (var x = pt2.X; x <= pt3.X; x++)
{
int maxY;
int minY = GetRange(line2Func(x), baseFunc(x), out maxY);
for (var y = minY; y <= maxY; y++)
{
yield return new Point(x, y);
}
}
}
private int GetRange(double y1, double y2, out int maxY)
{
if (y1 < y2)
{
maxY = (int)Math.Floor(y2);
return (int)Math.Ceiling(y1);
}
maxY = (int)Math.Floor(y1);
return (int)Math.Ceiling(y2);
}
private Func<int, double> CreateFunc(Point pt1, Point pt2)
{
var y0 = pt1.Y;
if (y0 == pt2.Y)
{
return x => y0;
}
var m = (double)(pt2.Y - y0) / (pt2.X - pt1.X);
return x => m * (x - pt1.X) + y0;
}
#SimpleVar answer is well, but it lacks a good check for valid triangles. (This can cause an overflow problem).
So I do my own implementation for Unity3D:
public static IEnumerable<T> PointsInTriangle<T>(T pt1, T pt2, T pt3)
where T : IPoint
{
/*
// https://www.geeksforgeeks.org/check-whether-triangle-valid-not-sides-given/
a + b > c
a + c > b
b + c > a
*/
float a = Vector2.Distance(new Vector2(pt1.x, pt1.y), new Vector2(pt2.x, pt2.y)),
b = Vector2.Distance(new Vector2(pt2.x, pt2.y), new Vector2(pt3.x, pt3.y)),
c = Vector2.Distance(new Vector2(pt3.x, pt3.y), new Vector2(pt1.x, pt1.y));
if (a + b <= c || a + c <= b || b + c <= a)
{
Debug.LogWarning($"The given points must form a triangle. {{{pt1}, {pt2}, {pt3}}}");
yield break;
}
if (TriangleArea(pt1, pt2, pt3) <= 1)
{
Point center = GetTriangleCenter(pt1, pt2, pt3);
yield return (T)Activator.CreateInstance(typeof(T), center.x, center.y);
return;
}
T tmp;
if (pt2.x < pt1.x)
{
tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
if (pt3.x < pt2.x)
{
tmp = pt2;
pt2 = pt3;
pt3 = tmp;
if (pt2.x < pt1.x)
{
tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
}
var baseFunc = CreateFunc(pt1, pt3);
var line1Func = pt1.x == pt2.x ? (x => pt2.y) : CreateFunc(pt1, pt2);
for (var x = pt1.x; x < pt2.x; ++x)
{
int maxY;
int minY = GetRange(line1Func(x), baseFunc(x), out maxY);
for (int y = minY; y <= maxY; ++y)
yield return (T)Activator.CreateInstance(typeof(T), x, y);
}
var line2Func = pt2.x == pt3.x ? (x => pt2.y) : CreateFunc(pt2, pt3);
for (var x = pt2.x; x <= pt3.x; ++x)
{
int maxY;
int minY = GetRange(line2Func(x), baseFunc(x), out maxY);
for (int y = minY; y <= maxY; ++y)
yield return (T)Activator.CreateInstance(typeof(T), x, y);
}
}
private static int GetRange(float y1, float y2, out int maxY)
{
if (y1 < y2)
{
maxY = Mathf.FloorToInt(y2);
return Mathf.CeilToInt(y1);
}
maxY = Mathf.FloorToInt(y1);
return Mathf.CeilToInt(y2);
}
private static Func<int, float> CreateFunc<T>(T pt1, T pt2)
where T : IPoint
{
var y0 = pt1.y;
if (y0 == pt2.y)
return x => y0;
float m = (float)(pt2.y - y0) / (pt2.x - pt1.x);
return x => m * (x - pt1.x) + y0;
}
public static float TriangleArea<T>(T p1, T p2, T p3)
where T : IPoint
{
float a, b, c;
if (!CheckIfValidTriangle(p1, p2, p3, out a, out b, out c))
return 0;
return TriangleArea(a, b, c);
}
public static float TriangleArea(float a, float b, float c)
{
// Thanks to: http://james-ramsden.com/area-of-a-triangle-in-3d-c-code/
float s = (a + b + c) / 2.0f;
return Mathf.Sqrt(s * (s - a) * (s - b) * (s - c));
}
public static Point GetTriangleCenter<T>(T p0, T p1, T p2)
where T : IPoint
{
// Thanks to: https://stackoverflow.com/questions/524755/finding-center-of-2d-triangle
return new Point(p0.x + p1.x + p2.x / 3, p0.y + p1.y + p2.y / 3);
}
public static bool CheckIfValidTriangle<T>(T v1, T v2, T v3, out float a, out float b, out float c)
where T : IPoint
{
a = Vector2.Distance(new Vector2(v1.x, v1.y), new Vector2(v2.x, v2.y));
b = Vector2.Distance(new Vector2(v2.x, v2.y), new Vector2(v3.x, v3.y));
c = Vector2.Distance(new Vector2(v3.x, v3.y), new Vector2(v1.x, v1.y));
if (a + b <= c || a + c <= b || b + c <= a)
return false;
return true;
}
IPoint interface could be a good point for own Point implementations (for libs like Clipper, TessDotNet or Poly2Tri). You can change it at any time (two UnityEngine.Vector2 or System.Drawing.Point).
Hope this helps!
EDIT: I solved all bugs here:
Also I answered my own question asking this: https://stackoverflow.com/a/53734816/3286975
I have two Line objects in C# WPF, and I'm trying to construct a method to work out the coordinates at which the lines intersect (if at all). After giving myself a headache reminding myself of high school maths to do this, I can't work out how to map it into programming format - anyone know how to do this?
Thanks very much,
Becky
I suppose your line objects are made up of two points. What you should do is get the equations of both lines.
Then you should solve the following equation:
equation-line1 = equation-line2
Calculate slope of a line:
float _slope = 1e+10;
if ((p2.x - p1.x) != 0)
_slope = (p2.y - p1.y) / (p2.x - p1.x);
p1 = Point 1 of your line
p2 = Point 2 of your line
Equation of a line:
y = ax + b
a = the slope you calculated
b = the intersect
Solving the equation:
a1 = p1.y - b1 * p1.x;
a2 = q1.y - b2 * q1.x;
x = (a1 - a2) / (b2 - b1);
y = a2 + b2 * x;
vars:
b1 = slope line 1
b2 = slop line 2
q1 = point 1 of your 2nd line
So, x and y are the coordinates of the point where the two lines intersect
This is more of a gee-whiz answer than a practical one, because if all you are doing is intersecting two lines it is very slow. However I thought it was worth a mention.
WPF has the ability to intersect any two shape outlines, including two lines, and tell you the location of the intersection.
Here is the general technique for intersecting two outlines (the edges, not the fill area):
var shape1 = ...;
var shape2 = ...;
var thinPen = new Pen(Brush.Transparent, 0.001);
var geometry1 = shape1.RenderedGeometry.GetWidenedPathGeometry(thinPen);
var geometry2 = shape2.RenderedGeometry.GetWidenedPathGeometry(thinPen);
var combined = Geometry.Combine(
geometry1,
geometry2,
GeometryCombineMode.Intersect,
shape2.TransformToVisual(shape1));
var bounds = combined.GetRenderBounds(thinPen);
If the shapes are known to have the same position the shape2.TransformToVisual(shape1) in the call to Geometry.Combine can be replaced with null.
This technique can be very useful, if, for example, you need to intersect a line with an arbitrary curve.
How to find intersection of two lines/segments/ray with rectangle
public class LineEquation{
public LineEquation(Point start, Point end){
Start = start;
End = end;
IsVertical = Math.Abs(End.X - start.X) < 0.00001f;
M = (End.Y - Start.Y)/(End.X - Start.X);
A = -M;
B = 1;
C = Start.Y - M*Start.X;
}
public bool IsVertical { get; private set; }
public double M { get; private set; }
public Point Start { get; private set; }
public Point End { get; private set; }
public double A { get; private set; }
public double B { get; private set; }
public double C { get; private set; }
public bool IntersectsWithLine(LineEquation otherLine, out Point intersectionPoint){
intersectionPoint = new Point(0, 0);
if (IsVertical && otherLine.IsVertical)
return false;
if (IsVertical || otherLine.IsVertical){
intersectionPoint = GetIntersectionPointIfOneIsVertical(otherLine, this);
return true;
}
double delta = A*otherLine.B - otherLine.A*B;
bool hasIntersection = Math.Abs(delta - 0) > 0.0001f;
if (hasIntersection){
double x = (otherLine.B*C - B*otherLine.C)/delta;
double y = (A*otherLine.C - otherLine.A*C)/delta;
intersectionPoint = new Point(x, y);
}
return hasIntersection;
}
private static Point GetIntersectionPointIfOneIsVertical(LineEquation line1, LineEquation line2){
LineEquation verticalLine = line2.IsVertical ? line2 : line1;
LineEquation nonVerticalLine = line2.IsVertical ? line1 : line2;
double y = (verticalLine.Start.X - nonVerticalLine.Start.X)*
(nonVerticalLine.End.Y - nonVerticalLine.Start.Y)/
((nonVerticalLine.End.X - nonVerticalLine.Start.X)) +
nonVerticalLine.Start.Y;
double x = line1.IsVertical ? line1.Start.X : line2.Start.X;
return new Point(x, y);
}
public bool IntersectWithSegementOfLine(LineEquation otherLine, out Point intersectionPoint){
bool hasIntersection = IntersectsWithLine(otherLine, out intersectionPoint);
if (hasIntersection)
return intersectionPoint.IsBetweenTwoPoints(otherLine.Start, otherLine.End);
return false;
}
public bool GetIntersectionLineForRay(Rect rectangle, out LineEquation intersectionLine){
if (Start == End){
intersectionLine = null;
return false;
}
IEnumerable<LineEquation> lines = rectangle.GetLinesForRectangle();
intersectionLine = new LineEquation(new Point(0, 0), new Point(0, 0));
var intersections = new Dictionary<LineEquation, Point>();
foreach (LineEquation equation in lines){
Point point;
if (IntersectWithSegementOfLine(equation, out point))
intersections[equation] = point;
}
if (!intersections.Any())
return false;
var intersectionPoints = new SortedDictionary<double, Point>();
foreach (var intersection in intersections){
if (End.IsBetweenTwoPoints(Start, intersection.Value) ||
intersection.Value.IsBetweenTwoPoints(Start, End)){
double distanceToPoint = Start.DistanceToPoint(intersection.Value);
intersectionPoints[distanceToPoint] = intersection.Value;
}
}
if (intersectionPoints.Count == 1){
Point endPoint = intersectionPoints.First().Value;
intersectionLine = new LineEquation(Start, endPoint);
return true;
}
if (intersectionPoints.Count == 2){
Point start = intersectionPoints.First().Value;
Point end = intersectionPoints.Last().Value;
intersectionLine = new LineEquation(start, end);
return true;
}
return false;
}
public override string ToString(){
return "[" + Start + "], [" + End + "]";
}
}
full sample is described here
I've managed to write a 'for dummies' how to calculate the area of irregular polygon in C#, but I need it to be dynamic for any amount of verticies.
Can someone please help?
Class:
public class Vertex
{
private int _vertexIdx;
private double _coordX;
private double _coordY;
private double _coordZ;
public Vertex()
{ }
public Vertex(int vertexIdx, double coordX, double coordY, double coordZ)
{
_vertexIdx = vertexIdx;
_coordX = coordX;
_coordY = coordY;
_coordZ = coordZ;
}
public int VertexIdx
{
get { return _vertexIdx; }
set { _vertexIdx = value; }
}
public double X
{
get { return _coordX; }
set { _coordX = value; }
}
public double Y
{
get { return _coordY; }
set { _coordY = value; }
}
public double Z
{
get { return _coordZ; }
set { _coordZ = value; }
}
}
Form_Load:
List<Vertex> verticies = new List<Vertex>();
verticies.Add(new Vertex(1, 930.9729, 802.8789, 0));
verticies.Add(new Vertex(2, 941.5341, 805.662, 0));
verticies.Add(new Vertex(3, 946.5828, 799.271, 0));
verticies.Add(new Vertex(4, 932.6215, 797.0548, 0));
dataGridView1.DataSource = verticies;
Code to calculate when button is pressed: (hard-coded for 4 points polygon - should be for any amount...)
// X-coords
double x1;
double x2;
double x3;
double x4;
double x5;
// Y-coords
double y1;
double y2;
double y3;
double y4;
double y5;
// Xn * Yn++
double x1y2;
double x2y3;
double x3y4;
double x4y5;
// Yn * Xn++
double y1x2;
double y2x3;
double y3x4;
double y4x5;
// XnYn++ - YnXn++
double x1y2my1x2;
double x2y3my2x3;
double x3y4my3x4;
double x4y5my4x5;
double result;
double area;
x1 = Convert.ToDouble(dataGridView1.Rows[0].Cells[1].Value.ToString());
y1 = Convert.ToDouble(dataGridView1.Rows[0].Cells[2].Value.ToString());
txtLog.Text += String.Format("X1 = {0}\tY1 = {1}\r\n", x1, y1);
x2 = Convert.ToDouble(dataGridView1.Rows[1].Cells[1].Value.ToString());
y2 = Convert.ToDouble(dataGridView1.Rows[1].Cells[2].Value.ToString());
txtLog.Text += String.Format("X2 = {0}\tY2 = {1}\r\n", x2, y2);
x3 = Convert.ToDouble(dataGridView1.Rows[2].Cells[1].Value.ToString());
y3 = Convert.ToDouble(dataGridView1.Rows[2].Cells[2].Value.ToString());
txtLog.Text += String.Format("X3 = {0}\tY3 = {1}\r\n", x3, y3);
x4 = Convert.ToDouble(dataGridView1.Rows[3].Cells[1].Value.ToString());
y4 = Convert.ToDouble(dataGridView1.Rows[3].Cells[2].Value.ToString());
txtLog.Text += String.Format("X4 = {0}\tY4 = {1}\r\n", x4, y4);
// add the start point again
x5 = Convert.ToDouble(dataGridView1.Rows[0].Cells[1].Value.ToString());
y5 = Convert.ToDouble(dataGridView1.Rows[0].Cells[2].Value.ToString());
txtLog.Text += String.Format("X5 = {0}\tY5 = {1}\r\n", x5, y5);
txtLog.Text += "\r\n";
// Multiply
x1y2 = x1 * y2;
x2y3 = x2 * y3;
x3y4 = x3 * y4;
x4y5 = x4 * y5;
y1x2 = y1 * x2;
y2x3 = y2 * x3;
y3x4 = y3 * x4;
y4x5 = y4 * x5;
// Subtract from each other
x1y2my1x2 = x1y2 - y1x2;
x2y3my2x3 = x2y3 - y2x3;
x3y4my3x4 = x3y4 - y3x4;
x4y5my4x5 = x4y5 - y4x5;
// Sum all results
result = x1y2my1x2 + x2y3my2x3 + x3y4my3x4 + x4y5my4x5;
area = Math.Abs(result / 2);
txtLog.Text += String.Format("Area = {0}\r\n", area);
Example output:
X1 = 930.9729
Y1 = 802.8789
X2 = 941.5341
Y2 = 805.662
X3 = 946.5828
Y3 = 799.271
X4 = 932.6215
Y4 = 797.0548
X5 = 930.9729
Y5 = 802.8789
Area = 83.2566504099523
Using lambda expressions this becomes trivial!
var points = GetSomePoints();
points.Add(points[0]);
var area = Math.Abs(points.Take(points.Count - 1)
.Select((p, i) => (points[i + 1].X - p.X) * (points[i + 1].Y + p.Y))
.Sum() / 2);
The algorithm is explained here:
[This method adds] the areas of the trapezoids defined by the polygon's edges dropped
to the X-axis. When the program considers a bottom edge of a polygon,
the calculation gives a negative area so the space between the polygon
and the axis is subtracted, leaving the polygon's area.
The total calculated area is negative if the polygon is oriented clockwise [so the] function simply returns the absolute value.
This method
gives strange results for non-simple polygons (where edges cross).
public float Area(List<PointF> vertices)
{
vertices.Add(vertices[0]);
return Math.Abs(vertices.Take(vertices.Count - 1).Select((p, i) => (p.X * vertices[i + 1].Y) - (p.Y * vertices[i + 1].X)).Sum() / 2);
}
Something like that for a plane polygon (compiled with notepad):
static double GetDeterminant(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
static double GetArea(IList<Vertex> vertices)
{
if(vertices.Count < 3)
{
return 0;
}
double area = GetDeterminant(vertices[vertices.Count - 1].X, vertices[vertices.Count - 1].Y, vertices[0].X, vertices[0].Y);
for (int i = 1; i < vertices.Count; i++)
{
area += GetDeterminant(vertices[i - 1].X, vertices[i - 1].Y, vertices[i].X, vertices[i].Y);
}
return area / 2;
}
Although your approach doesn't pay attention to Z-axis. Therefore I'd advice to apply some transformation to get rid of it: you won't be able to get area if the polygon is not plane, whereas if it is plane you are able to get rid of the third dimension.
I've found that when calculating the area for approx 600,000 polygons, the basic formulae shown above worked for some polygons, but a lot were out by a huge degree. I was spot checking my results against https://geojson.io/ - which returned correct results for very complex polygons with holes in them (e.g. lakes in the middle). In order to calculate the correct area for a complex polygon, I ended up using the same system that geojson.io uses - a client side js library Turf.js see here https://turfjs.org/docs/#area
In this image, you can see my first try, then my second using Turf.js - there is a column there showing a ratio of how correct the first try was compared to the second where 1 is the same calculation. You can see that they are mostly close, but some are out by a factor of 10 or worse.
Here is some sample code to do the calculation. I had it load 200 onto the screen, then run the calculation in JS, and ajax the result back to the server side database.
$(document).ready(function () {
var items = $('.geojson');
for (var sc = 0; sc < items.length; sc++) {
var id = $(items[sc]).attr('data-id');
var polyData = JSON.parse($(items[sc]).find('.geojson-data').html());
//console.log('[' + polyData + ']');
var polygon = turf.polygon(polyData.coordinates);
var area = turf.area(polygon);
console.log('id[' + id + ']sqm[' + area + ']');
$(items[sc]).closest('tr').find('.data-id').html(id);
var answerDom = $(items[sc]).closest('tr').find('.answer');
if (true) {
$.ajax({
url: 'calc-poly-area-from-geojson-turf-scheduled.aspx',
type: "get",
data: {id:id, area: area },
invokedata: { answerDom: answerDom, area: area },
async: true,//run all at the same time
cache: false,
success: function (data) {
//console.log('test email done');
$(this.invokedata.answerDom).html('ok:' + this.invokedata.area);
$(this.invokedata.answerDom).removeClass('answer');
if ($('.answer').length == 0) {
window.location.reload();
}
},
error: function (msg) {
console.log("call failed: " + msg.responseText);
$(el).html('error in call');
//prompt('copy this',url+'?'+qs)
}
});
}
}
});
window.setTimeout(function () { window.location.reload(); }, 10000);
where an example polygon is here
{"type":"Polygon", "coordinates":[[[171.519147876006,-43.809111826162],[171.519264282931,-43.8094307100015],[171.519615782201,-43.8097268361192],[171.519874096036,-43.8097860548424],[171.525264107563,-43.8176887926426],[171.525356625489,-43.8179845471556],[171.525750029905,-43.8185636705947],[171.526002901974,-43.8187934292356],[171.526154917292,-43.8189686576417],[171.526249645477,-43.8191111884506],[171.526245660987,-43.819269203656],[171.526032299227,-43.8200263808647],[171.524134038501,-43.8268225827224],[171.523301803308,-43.8297987275054],[171.523129147529,-43.8301621243769],[171.522991616155,-43.8300725313285],[171.52248605771,-43.8302181414427],[171.522128893843,-43.8304084928376],[171.521558488905,-43.8304389785399],[171.521371202269,-43.830481916342],[171.521023295734,-43.8309120441211],[171.520774217465,-43.8310054055632],[171.520589483523,-43.8311387384524],[171.515210823266,-43.8294163992962],[171.514763136723,-43.8292736695248],[171.496256757791,-43.8233680542711],[171.494338310605,-43.8227558913632],[171.493450128779,-43.8224739752289],[171.493221517911,-43.8223838125259],[171.493001278557,-43.8222877021167],[171.492654147639,-43.821801588707],[171.491048512765,-43.8200169686591],[171.488157604579,-43.8168246695455],[171.488051808197,-43.8166695752984],[171.487648717141,-43.8162207994268],[171.486147094889,-43.8145461538075],[171.482241975825,-43.8101769774879],[171.481683765874,-43.8095751045999],[171.480858016595,-43.8085443728491],[171.481124633337,-43.8086557677844],[171.481334008334,-43.8085534985925],[171.481540735171,-43.8083379086683],[171.4815994175,-43.8077828104991],[171.481763314624,-43.8074471226617],[171.481812168914,-43.8064706917151],[171.48196041271,-43.8063093336607],[171.482260412185,-43.8062322290662],[171.482916004007,-43.8059780008537],[171.494844864468,-43.8013540958407],[171.501308718774,-43.7988446798756],[171.506019390319,-43.797017657826],[171.508275460952,-43.7961421972998],[171.508430707528,-43.7960805551645],[171.509117292333,-43.7963432108869],[171.510511038963,-43.7968679021071],[171.513299102675,-43.8007637699317],[171.513465917258,-43.8010892007185],[171.513696634335,-43.8013818859084],[171.513929550742,-43.8016136793445],[171.514114411714,-43.8018826827151],[171.514305634465,-43.8021912982997],[171.51440028511,-43.8024789426394],[171.514828618996,-43.8028429251794],[171.51494106207,-43.8031623582355],[171.515852739466,-43.8044825303059],[171.516111930457,-43.8047763591375],[171.517116748697,-43.8062534995253],[171.517374596163,-43.8065473602078],[171.517549793874,-43.8068229401963],[171.5176213721,-43.8070824951625],[171.517796573697,-43.8073580748019],[171.518070610117,-43.8076087983324],[171.518880109148,-43.8088563353488],[171.519147876006,-43.809111826162]]]}
you can paste that into geojson.io to check their area (click on poly, then 'properties' tab)