public void calculateVisibleElements(Envelope envelope, int zoom) {
    if (zoom < minZoom) {
      setVisibleElementsList(null);
      return;
    }

    if (userColumns[0] == null) return;

    if (renderOnce) {
      renderOnce = false;

      List<Geometry> geometries = spatialiteLayer.getVisibleElements();
      if (geometries == null || geometries.size() == 0) {
        setVisibleElementsList(null);
        return;
      }

      objects = new Vector<Text>();

      for (Geometry geom : geometries) {

        GeometryData userData = (GeometryData) geom.userData;
        String name = userData.label;

        MapPos topRight = null;
        if (geom instanceof Point) {
          topRight = ((Point) geom).getMapPos();
        } else if (geom instanceof Line) {
          topRight = ((Line) geom).getVertexList().get(0);
        } else if (geom instanceof Polygon) {
          try {
            MapPos center =
                SpatialiteUtil.computeCentroid((Polygon) GeometryUtil.convertGeometryToWgs84(geom));
            topRight = GeometryUtil.convertFromWgs84(center);
          } catch (Exception e) {
            topRight = new MapPos(0, 0);
            FLog.e("error computing centroid of polygon", e);
          }
        } else {
          FLog.e("invalid geometry type");
        }

        Text newText = new Text(topRight, name, styleSet, null);

        newText.attachToLayer(this);
        newText.setActiveStyle(zoom);

        objects.add(newText);
      }

      setVisibleElementsList(objects);
    }
  }
  public void createElementsInLayer(
      int zoom, Vector<Geometry> objectTemp, Vector<Geometry> objects, GeometryData.Type dataType) {

    // apply styles, create new objects for these
    for (Geometry object : objectTemp) {

      Geometry newObject = null;
      String[] userData = (String[]) object.userData;
      GeometryStyle style = getGeometryStyle(object, userData[0]);
      GeometryData geomData = new GeometryData(userData[0], dataType, userData[1], style, layerId);

      if (hideGeometryList.contains(geomData.id)) continue;

      if (object instanceof Point) {
        newObject =
            new Point(((Point) object).getMapPos(), null, style.toPointStyleSet(), geomData);
      } else if (object instanceof Line) {
        newObject =
            new Line(((Line) object).getVertexList(), null, style.toLineStyleSet(), geomData);
      } else if (object instanceof Polygon) {
        newObject =
            new Polygon(
                ((Polygon) object).getVertexList(),
                ((Polygon) object).getHolePolygonList(),
                null,
                style.toPolygonStyleSet(),
                geomData);
      }

      Geometry transformedObject = GeometryUtil.convertGeometryFromWgs84(newObject);

      transformedObject.attachToLayer(this);
      transformedObject.setActiveStyle(zoom);

      objects.add(transformedObject);
    }
  }
 /**
  * Determines whether the segment defined by the point at the specified index and its successor is
  * horizontal or not.
  *
  * @param index the start index of the segment
  * @return true if horizontal, false if vertical
  */
 private boolean isSegmentHorizontal(int index) {
   Point2D p1 = getConnection().getPoints().get(index);
   Point2D p2 = getConnection().getPoints().get(index + 1);
   return GeometryUtil.getInstance().getSegmentOrientation(p1, p2) == Orientation.HORIZONTAL;
 }
 /**
  * Because of rounding errors caused by scaling, a custom outcode() method is provided here.
  *
  * @param bounds the Rectangle2D
  * @param point the Point2D
  * @return the outcode
  */
 private int outcode(Rectangle2D bounds, Point2D point) {
   return GeometryUtil.getInstance().outcode(bounds, point);
 }
  public IntersectPoint[] findCrossing() {
    double[] edge1 = new double[8];
    double[] edge2 = new double[8];
    double[] points = new double[6];
    double[] params = new double[6];
    double[] mp1 = new double[2];
    double[] cp1 = new double[2];
    double[] mp2 = new double[2];
    double[] cp2 = new double[2];
    int rule1, rule2, endIndex1, endIndex2;
    int ipCount = 0;

    for (int i = 0; i < rulesSizes[0]; i++) {
      rule1 = rules[0][i];
      endIndex1 = getCurrentEdge(0, i, edge1, mp1, cp1);
      for (int j = 0; j < rulesSizes[1]; j++) {
        ipCount = 0;
        rule2 = rules[1][j];
        endIndex2 = getCurrentEdge(1, j, edge2, mp2, cp2);
        if (((rule1 == PathIterator.SEG_LINETO) || (rule1 == PathIterator.SEG_CLOSE))
            && ((rule2 == PathIterator.SEG_LINETO) || (rule2 == PathIterator.SEG_CLOSE))) {

          ipCount =
              GeometryUtil.intersectLinesWithParams(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge2[0], edge2[1], edge2[2], edge2[3],
                  params);

          if (ipCount != 0) {
            points[0] = GeometryUtil.line(params[0], edge1[0], edge1[2]);
            points[1] = GeometryUtil.line(params[0], edge1[1], edge1[3]);
          }
        } else if (((rule1 == PathIterator.SEG_LINETO) || (rule1 == PathIterator.SEG_CLOSE))
            && (rule2 == PathIterator.SEG_QUADTO)) {
          ipCount =
              GeometryUtil.intersectLineAndQuad(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge2[0], edge2[1], edge2[2], edge2[3],
                  edge2[4], edge2[5], params);
          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.line(params[2 * k], edge1[0], edge1[2]);
            points[2 * k + 1] = GeometryUtil.line(params[2 * k], edge1[1], edge1[3]);
          }
        } else if (rule1 == PathIterator.SEG_QUADTO
            && (rule2 == PathIterator.SEG_LINETO || rule2 == PathIterator.SEG_CLOSE)) {
          ipCount =
              GeometryUtil.intersectLineAndQuad(
                  edge2[0], edge2[1], edge2[2], edge2[3], edge1[0], edge1[1], edge1[2], edge1[3],
                  edge1[4], edge1[5], params);
          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.line(params[2 * k + 1], edge2[0], edge2[2]);
            points[2 * k + 1] = GeometryUtil.line(params[2 * k + 1], edge2[1], edge2[3]);
          }
        } else if ((rule1 == PathIterator.SEG_CUBICTO)
            && ((rule2 == PathIterator.SEG_LINETO) || (rule2 == PathIterator.SEG_CLOSE))) {
          ipCount =
              GeometryUtil.intersectLineAndCubic(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge1[4], edge1[5], edge1[6], edge1[7],
                  edge2[0], edge2[1], edge2[2], edge2[3], params);

          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.line(params[2 * k + 1], edge2[0], edge2[2]);
            points[2 * k + 1] = GeometryUtil.line(params[2 * k + 1], edge2[1], edge2[3]);
          }
        } else if (((rule1 == PathIterator.SEG_LINETO) || (rule1 == PathIterator.SEG_CLOSE))
            && (rule2 == PathIterator.SEG_CUBICTO)) {
          ipCount =
              GeometryUtil.intersectLineAndCubic(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge2[0], edge2[1], edge2[2], edge2[3],
                  edge2[4], edge2[5], edge2[6], edge2[7], params);

          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.line(params[2 * k], edge1[0], edge1[2]);
            points[2 * k + 1] = GeometryUtil.line(params[2 * k], edge1[1], edge1[3]);
          }
        } else if ((rule1 == PathIterator.SEG_QUADTO) && (rule2 == PathIterator.SEG_QUADTO)) {
          ipCount =
              GeometryUtil.intersectQuads(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge1[4], edge1[5], edge2[0], edge2[1],
                  edge2[2], edge2[3], edge2[4], edge2[5], params);
          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.quad(params[2 * k], edge1[0], edge1[2], edge1[4]);
            points[2 * k + 1] = GeometryUtil.quad(params[2 * k], edge1[1], edge1[3], edge1[5]);
          }
        } else if ((rule1 == PathIterator.SEG_QUADTO) && (rule2 == PathIterator.SEG_CUBICTO)) {
          ipCount =
              GeometryUtil.intersectQuadAndCubic(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge1[4], edge1[5], edge2[0], edge2[1],
                  edge2[2], edge2[3], edge2[4], edge2[5], edge2[6], edge2[7], params);

          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.quad(params[2 * k], edge1[0], edge1[2], edge1[4]);
            points[2 * k + 1] = GeometryUtil.quad(params[2 * k], edge1[1], edge1[3], edge1[5]);
          }
        } else if ((rule1 == PathIterator.SEG_CUBICTO) && (rule2 == PathIterator.SEG_QUADTO)) {
          ipCount =
              GeometryUtil.intersectQuadAndCubic(
                  edge2[0], edge2[1], edge2[2], edge2[3], edge2[4], edge2[5], edge1[0], edge1[1],
                  edge1[2], edge1[3], edge1[4], edge1[5], edge2[6], edge2[7], params);

          for (int k = 0; k < ipCount; k++) {
            points[2 * k] = GeometryUtil.quad(params[2 * k + 1], edge2[0], edge2[2], edge2[4]);
            points[2 * k + 1] = GeometryUtil.quad(params[2 * k + 1], edge2[1], edge2[3], edge2[5]);
          }
        } else if ((rule1 == PathIterator.SEG_CUBICTO) && (rule2 == PathIterator.SEG_CUBICTO)) {
          ipCount =
              GeometryUtil.intersectCubics(
                  edge1[0], edge1[1], edge1[2], edge1[3], edge1[4], edge1[5], edge1[6], edge1[7],
                  edge2[0], edge2[1], edge2[2], edge2[3], edge2[4], edge2[5], edge2[6], edge2[7],
                  params);

          for (int k = 0; k < ipCount; k++) {
            points[2 * k] =
                GeometryUtil.cubic(params[2 * k], edge1[0], edge1[2], edge1[4], edge1[6]);
            points[2 * k + 1] =
                GeometryUtil.cubic(params[2 * k], edge1[1], edge1[3], edge1[5], edge1[7]);
          }
        }

        endIndex1 = i;
        endIndex2 = j;
        int begIndex1 = i - 1;
        int begIndex2 = j - 1;

        for (int k = 0; k < ipCount; k++) {
          IntersectPoint ip = null;
          if (!containsPoint(points[2 * k], points[2 * k + 1])) {
            for (Iterator<IntersectPoint> iter = isectPoints.iterator(); iter.hasNext(); ) {
              ip = iter.next();
              if ((begIndex1 == ip.getBegIndex(true)) && (endIndex1 == ip.getEndIndex(true))) {

                if (ip.getParam(true) > params[2 * k]) {
                  endIndex1 = -(isectPoints.indexOf(ip) + 1);
                  ip.setBegIndex1(-(isectPoints.size() + 1));
                } else {
                  begIndex1 = -(isectPoints.indexOf(ip) + 1);
                  ip.setEndIndex1(-(isectPoints.size() + 1));
                }
              }

              if ((begIndex2 == ip.getBegIndex(false)) && (endIndex2 == ip.getEndIndex(false))) {

                if (ip.getParam(false) > params[2 * k + 1]) {
                  endIndex2 = -(isectPoints.indexOf(ip) + 1);
                  ip.setBegIndex2(-(isectPoints.size() + 1));
                } else {
                  begIndex2 = -(isectPoints.indexOf(ip) + 1);
                  ip.setEndIndex2(-(isectPoints.size() + 1));
                }
              }
            }

            if (rule1 == PathIterator.SEG_CLOSE) {
              rule1 = PathIterator.SEG_LINETO;
            }

            if (rule2 == PathIterator.SEG_CLOSE) {
              rule2 = PathIterator.SEG_LINETO;
            }

            isectPoints.add(
                new IntersectPoint(
                    begIndex1,
                    endIndex1,
                    rule1,
                    i,
                    begIndex2,
                    endIndex2,
                    rule2,
                    j,
                    points[2 * k],
                    points[2 * k + 1],
                    params[2 * k],
                    params[2 * k + 1]));
          }
        }
      }
    }
    return isectPoints.toArray(new IntersectPoint[isectPoints.size()]);
  }