All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.shaded.org.apache.calcite.runtime.SplitOperation Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hazelcast.shaded.org.apache.calcite.runtime;

import com.hazelcast.shaded.org.locationtech.jts.algorithm.LineIntersector;
import com.hazelcast.shaded.org.locationtech.jts.algorithm.RobustLineIntersector;
import com.hazelcast.shaded.org.locationtech.jts.geom.Coordinate;
import com.hazelcast.shaded.org.locationtech.jts.geom.Geometry;
import com.hazelcast.shaded.org.locationtech.jts.geom.GeometryCollection;
import com.hazelcast.shaded.org.locationtech.jts.geom.GeometryFactory;
import com.hazelcast.shaded.org.locationtech.jts.geom.LineString;
import com.hazelcast.shaded.org.locationtech.jts.geom.MultiLineString;
import com.hazelcast.shaded.org.locationtech.jts.geom.MultiPolygon;
import com.hazelcast.shaded.org.locationtech.jts.geom.Point;
import com.hazelcast.shaded.org.locationtech.jts.geom.Polygon;
import com.hazelcast.shaded.org.locationtech.jts.geom.util.LineStringExtracter;
import com.hazelcast.shaded.org.locationtech.jts.operation.polygonize.Polygonizer;

import java.util.ArrayList;
import java.util.List;

/**
 * Splits {@code geom} by {@code blade}.
 */
public class SplitOperation {

  private final Geometry geom;

  private final Geometry blade;

  public SplitOperation(Geometry geom, Geometry blade) {
    this.geom = geom;
    this.blade = blade;
  }

  public Geometry split() {
    if (geom instanceof LineString && blade instanceof Point) {
      return split((LineString) geom, (Point) blade);

    } else if (geom instanceof LineString && blade instanceof LineString) {
      return split((LineString) geom, (LineString) blade);

    } else if (geom instanceof MultiLineString && blade instanceof Point) {
      return split((MultiLineString) geom, (Point) blade);

    } else if (geom instanceof MultiLineString && blade instanceof LineString) {
      return split((MultiLineString) geom, (LineString) blade);

    } else if (geom instanceof Polygon && blade instanceof LineString) {
      return split((Polygon) geom, (LineString) blade);

    } else if (geom instanceof MultiPolygon && blade instanceof LineString) {
      return split((MultiPolygon) geom, (LineString) blade);

    } else {
      throw new UnsupportedOperationException(
          "Split operation not supported for "
              + geom.getGeometryType() + " and "
              + blade.getGeometryType());
    }
  }

  private static Geometry split(LineString geometry, Point blade) {
    GeometryFactory factory = geometry.getFactory();

    Coordinate[] coordinates = geometry.getCoordinates();
    LineIntersector intersector = new RobustLineIntersector();
    Coordinate p = blade.getCoordinate();

    List accumulator = new ArrayList<>();
    List lines = new ArrayList<>();

    for (int i = 1; i < coordinates.length; i++) {
      Coordinate p1 = coordinates[i - 1];
      Coordinate p2 = coordinates[i];

      accumulator.add(p1.copy());

      intersector.computeIntersection(p, p1, p2);
      if (intersector.hasIntersection()) {
        accumulator.add(p.copy());
        LineString line =
            factory.createLineString(accumulator.toArray(new Coordinate[0]));
        lines.add(line);

        accumulator.clear();
        accumulator.add(p.copy());
      }
    }

    accumulator.add(coordinates[coordinates.length - 1].copy());
    LineString line =
        factory.createLineString(accumulator.toArray(new Coordinate[0]));
    lines.add(line);

    if (lines.size() == 1) {
      return lines.get(0);
    } else {
      return factory.buildGeometry(lines);
    }
  }

  private static Geometry split(MultiLineString geometry, Point blade) {
    GeometryFactory factory = geometry.getFactory();
    List geometries = new ArrayList<>();
    for (int i = 0; i < geometry.getNumGeometries(); i++) {
      Geometry split = split((LineString) geometry.getGeometryN(i), blade);
      if (split instanceof GeometryCollection) {
        for (int j = 0; j < split.getNumGeometries(); j++) {
          geometries.add(split.getGeometryN(j));
        }
      } else {
        geometries.add(split);
      }
    }
    return factory.buildGeometry(geometries);
  }

  private static Geometry split(LineString geometry, LineString blade) {
    return geometry.difference(blade);
  }

  private static Geometry split(MultiLineString geometry, LineString blade) {
    return geometry.difference(blade);
  }

  private static Geometry split(Polygon geometry, LineString blade) {
    GeometryFactory factory = geometry.getFactory();
    List polygons = new ArrayList<>();
    Geometry union = geometry.getBoundary().union(blade);
    Polygonizer polygonizer = new Polygonizer();
    polygonizer.add(LineStringExtracter.getLines(union));
    for (Polygon p : GeometryFactory.toPolygonArray(polygonizer.getPolygons())) {
      if (geometry.contains(geometry.getInteriorPoint())) {
        p.normalize();
        polygons.add(p);
      }
    }
    return factory.buildGeometry(polygons);
  }

  private static Geometry split(MultiPolygon geometry, LineString blade) {
    GeometryFactory factory = geometry.getFactory();
    List geometries = new ArrayList<>();
    for (int i = 0; i < geometry.getNumGeometries(); i++) {
      Geometry split = split((Polygon) geometry.getGeometryN(i), blade);
      if (split instanceof GeometryCollection) {
        for (int j = 0; j < split.getNumGeometries(); j++) {
          geometries.add(split.getGeometryN(j));
        }
      } else {
        geometries.add(split);
      }
    }
    return factory.buildGeometry(geometries);
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy