Exemplo n.º 1
0
    def Compute(self, reverse=False, sign=True):
        """Compute the properties of the polygon

        :param reverse: if true then clockwise (instead of
        counter-clockwise) traversal counts as a positive area
        :param sign: if true then return a signed result for the area if the
        polygon is traversed in the "wrong" direction instead of returning
        the area for the rest of the earth
        :return: a tuple of number, perimeter (meters), area (meters^2)

        If the object is a polygon (and not a polygon), the perimeter
        includes the length of a final edge connecting the current point to
        the initial point.  If the object is a polyline, then area is nan.

        More points can be added to the polygon after this call.

        """
        if self.polyline:
            area = Math.NAN
        if self.num < 2:
            perimeter = 0.0
            if not self.polyline:
                area = 0.0
            return self.num, perimeter, area

        if self.polyline:
            perimeter = self._perimetersum.Sum()
            return self.num, perimeter, area

        _, s12, _, _, _, _, _, _, _, S12 = self.earth._GenInverse(
            self.lat1, self.lon1, self._lat0, self._lon0, self._mask
        )
        perimeter = self._perimetersum.Sum(s12)
        tempsum = Accumulator(self._areasum)
        tempsum.Add(S12)
        crossings = self._crossings + PolygonArea._transit(self.lon1, self._lon0)
        if crossings & 1:
            tempsum.Add((1 if tempsum.Sum() < 0 else -1) * self.area0 / 2)
        # area is with the clockwise sense.  If !reverse convert to
        # counter-clockwise convention.
        if not reverse:
            tempsum.Negate()
        # If sign put area in (-area0/2, area0/2], else put area in [0, area0)
        if sign:
            if tempsum.Sum() > self.area0 / 2:
                tempsum.Add(-self.area0)
            elif tempsum.Sum() <= -self.area0 / 2:
                tempsum.Add(self.area0)
        else:
            if tempsum.Sum() >= self.area0:
                tempsum.Add(-self.area0)
            elif tempsum.Sum() < 0:
                tempsum.Add(self.area0)

        area = 0.0 + tempsum.Sum()
        return self.num, perimeter, area