需求是要将一个面用线将其分割成两块或多块的面。这个面包括多路径面的极端情况。
在ArcGIS For Android提供的API中 GeometryEngine工具类中未有Segment这个方法,在官网查阅中发现在最新的100.0.0版本中是有这个方法的,但是项目中使用的是10.2.8的版本,Eris在这两个版本变化很大,要换SDK十分麻烦,要更换和地图有关的所有地方,所以只能自己动手去写这个分割逻辑。
具体代码
private void previousSegmentation(Geometry gonGeo, Geometry lineGeo) {
// 这个面的集合用来做遍历
List<Geometry> gonGraphics = new ArrayList<Geometry>();
// 取线的最后一个点 判断是否穿过面
MultiPath multiPath = (MultiPath) lineGeo;
MultiPath multiPathGon = (MultiPath) gonGeo;
boolean isIsland = false;
Point pointLast = multiPath.getPoint(multiPath.getPointCount() - 1);
Point pointFirst = multiPath.getPoint(0);
// 判断分割首要条件为线与面相交,并且线的第一个点与最后一个点不和面相交
if (!GeometryEngine.intersects(gonGeo, pointFirst, mMapView.getSpatialReference())
&& !GeometryEngine.intersects(gonGeo, pointLast, mMapView.getSpatialReference())
&& GeometryEngine.intersects(gonGeo, lineGeo, mMapView.getSpatialReference())
) {
// 遍历多路径 生成面集合
SegmentIterator segmentIterator = multiPathGon.querySegmentIterator();
while (segmentIterator.nextPath()) {
Polygon polygonPath = new Polygon();
while (segmentIterator.hasNextSegment()) {
polygonPath.addSegment(segmentIterator.nextSegment(), false);
}
polygonPath.removePoint(polygonPath.getPointCount() - 1);
gonGraphics.add(polygonPath);
}
if (gonGraphics.size() > 1) {
// 对自身集合遍历 判断是否是环岛面
for (int i = 0; i < gonGraphics.size(); i++) {
for (int j = 0; j < gonGraphics.size(); j++) {
if (i != j && GeometryEngine.contains(gonGraphics.get(i),
gonGraphics.get(j), mMapView.getSpatialReference())) {
isIsland = true;
break;
}
}
}
}
if (isIsland) { // 如果是环岛面
List<List<Geometry>> doubleGeo = new ArrayList<List<Geometry>>();
// 第一步 区分大面和小面
// 对面集合进行按面积大小的冒泡排序
for (int k = 0; k < gonGraphics.size(); k++) {
for (int z = 0; z < gonGraphics.size() - 1 - k; z++) {
double index = Math.abs(gonGraphics.get(z).calculateArea2D());
double index1 = Math.abs(gonGraphics.get(z + 1).calculateArea2D());
if (index < index1) {
gonGraphics.add(z, gonGraphics.get(z + 1));
gonGraphics.remove(z + 2);
}
}
}
// 对面进行分组
for (int i = 0; i < gonGraphics.size(); i++) {
List<Geometry> singleGeo = new ArrayList<Geometry>();
if (gonGraphics.get(i).calculateArea2D() > 0) {// 环岛小面的面积是负数
for (int j = 0; j < gonGraphics.size(); j++) {
if (i != j && GeometryEngine.contains(gonGraphics.get(i),
gonGraphics.get(j), mMapView.getSpatialReference())) {
if (singleGeo.isEmpty()) {// 如果暂时没有面 则是未放入大面
singleGeo.add(gonGraphics.get(i));// 取到大面
}
singleGeo.add(gonGraphics.get(j));// 取到被包含的小面
}
}
if (singleGeo.isEmpty()) {// 是空的情况 就是单一的普通的面
singleGeo.add(gonGraphics.get(i));
}// 不是空的情况 就是有环岛的面
doubleGeo.add(singleGeo);
}
}
// 存放结果的集合
List<Geometry> result = new ArrayList<Geometry>();
for (int a = 0; a < doubleGeo.size(); a+