Android Google 未根据给定的坐标集绘制地图多边形选项
Android Google Maps PolygonOptions not plotted from given set of coordinates
我正在尝试围绕一条路线绘制一个复杂的多边形,按照给定半径的步骤进行。为此,我在路线的每一步(坐标)周围绘制了 50 条边的均匀多边形(实际上是圆形)。现在我获得了路线周围所有绘制圆圈的一组坐标,我可以在地图上看到它们,但它们是重叠的,这不是很好看,在上面添加如此大量的叠加层不是一个好习惯地图。
所以我现在需要做的是将我现在拥有的所有多边形合并为一个多边形并将其绘制在地图上。
我尝试删除每两个多边形的交点(测试 polygon1 的点是否位于 polygon2 内部,反之亦然)并将所有其余坐标合并到一个数组中,然后构建我的新多边形,但它没有工作。这是我如何执行此操作的代码片段:
public ArrayList<PolygonOptions> polygons = new ArrayList<>();
// lineOptions is the set of route coordinates
for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
// Draw a circle around each point of the route
PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);
// Draw a convex hull between every two successive circles
PolygonOptions convexHull = convexHull(circle1, circle2);
convexHull.strokeWidth(0);
convexHull.fillColor(0x7F729E47);
activity.range.add(activity.mMap.addPolygon(convexHull));
polygons.add(convexHull);
}
if (polygons.size() == 1) {
pts.addAll(polygons.get(0).getPoints());
} else {
for (int i = 0; i < polygons.size() - 1; i++) {
ArrayList<LatLng> pts1 = new ArrayList<>();
ArrayList<LatLng> pts2 = new ArrayList<>();
pts1.addAll(polygons.get(i).getPoints());
pts2.addAll(polygons.get(i + 1).getPoints());
for (int j = 0; j < pts1.size(); j++) {
if (pointInPolygon(pts1.get(j), pts2)) {
pts1.remove(j);
}
}
for (int j = 0; j < pts2.size(); j++) {
if (pointInPolygon(pts2.get(j), pts1)) {
pts2.remove(j);
}
}
pts.addAll(pts1);
pts.addAll(pts2);
}
}
// This part didn't work
// PolygonOptions range = new PolygonOptions();
// range.addAll(pts);
// range.strokeWidth(0);
// range.fillColor(0x7F729E47);
// activity.range.add(activity.mMap.addPolygon(range));
您需要计算行的缓冲区。根据Wikipedia:
A buffer is an area defined by the bounding region determined by a set of points at a specified maximum distance from all nodes along segments of an object.
几何的缓冲区是使用 Minkowski sum 计算的。 Minkowsky 求和采用两个多边形(一个是折线,另一个是圆形,如果你想要圆角)并移动第二个通过第一个的路径。
您可以找到一些您可以研究的 Minkowski 和的具体实现。例如https://github.com/perelo/computational-geometry/blob/master/src/computational_geometry/model/algorithms/Minkowski.java
按照@antonio 的指示,并使用 JTS Topology Suit,我能够在路线周围绘制一个具有定义半径的多边形(缓冲路线)。当我使用 JTS 库中的缓冲区函数时,我获得了路线的缓冲区,但上限是椭圆形的,我读到了它,发生这种情况是因为计算的坐标投影在不平坦的地球地图上,上限变得更椭圆当路线靠近地球两极时,当靠近赤道线(0º 纬度)时更圆。无论如何,我使用了库中的另一个功能来合并我的问题中已有的所有多边形,结果如下:
public ArrayList<Polygon> polys = new ArrayList<>();
//lineOptions is the set of route coordinates
for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
// Draw a circle around each point of the route
PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);
// Draw a convex hull between every two successive circles
PolygonOptions convexHull = convexHull(circle1, circle2);
List<LatLng> latLngs = convexHull.getPoints();
List<Coordinate> coords = new ArrayList<>();
for (int j=0; j<latLngs.size(); j++) {
coords.add(new Coordinate(latLngs.get(j).latitude, latLngs.get(j).longitude));
if(j==latLngs.size()-1)
coords.add(new Coordinate(latLngs.get(0).latitude, latLngs.get(0).longitude));
}
Coordinate[] coordinates = coords.toArray(new Coordinate[coords.size()]);
GeometryFactory fact = new GeometryFactory();
LinearRing linear = new GeometryFactory().createLinearRing(coordinates);
Polygon poly = new Polygon(linear, null, fact);
polys.add(poly);
}
PolygonOptions combine = combineIntoOnePolygon(polys);
combine.strokeWidth(0);
combine.fillColor(0x7F729E47);
activity.range = activity.mMap.addPolygon(combine);
合并函数:
static PolygonOptions combineIntoOnePolygon(Collection<Polygon> geometries ){
Geometry all = null;
PolygonOptions allPolygon = new PolygonOptions();
for(Iterator<Polygon> i = geometries.iterator(); i.hasNext(); ){
Polygon geometry = i.next();
if( geometry == null ) continue;
if( all == null ){
all = geometry;
}
else {
all = all.union( geometry );
}
}
List<Coordinate> bufferCoordinates = Arrays.asList(all.getCoordinates());
for (Coordinate c : bufferCoordinates) {
allPolygon.add(new LatLng(c.x, c.y));
}
return allPolygon;
}
我正在尝试围绕一条路线绘制一个复杂的多边形,按照给定半径的步骤进行。为此,我在路线的每一步(坐标)周围绘制了 50 条边的均匀多边形(实际上是圆形)。现在我获得了路线周围所有绘制圆圈的一组坐标,我可以在地图上看到它们,但它们是重叠的,这不是很好看,在上面添加如此大量的叠加层不是一个好习惯地图。
所以我现在需要做的是将我现在拥有的所有多边形合并为一个多边形并将其绘制在地图上。
我尝试删除每两个多边形的交点(测试 polygon1 的点是否位于 polygon2 内部,反之亦然)并将所有其余坐标合并到一个数组中,然后构建我的新多边形,但它没有工作。这是我如何执行此操作的代码片段:
public ArrayList<PolygonOptions> polygons = new ArrayList<>();
// lineOptions is the set of route coordinates
for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
// Draw a circle around each point of the route
PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);
// Draw a convex hull between every two successive circles
PolygonOptions convexHull = convexHull(circle1, circle2);
convexHull.strokeWidth(0);
convexHull.fillColor(0x7F729E47);
activity.range.add(activity.mMap.addPolygon(convexHull));
polygons.add(convexHull);
}
if (polygons.size() == 1) {
pts.addAll(polygons.get(0).getPoints());
} else {
for (int i = 0; i < polygons.size() - 1; i++) {
ArrayList<LatLng> pts1 = new ArrayList<>();
ArrayList<LatLng> pts2 = new ArrayList<>();
pts1.addAll(polygons.get(i).getPoints());
pts2.addAll(polygons.get(i + 1).getPoints());
for (int j = 0; j < pts1.size(); j++) {
if (pointInPolygon(pts1.get(j), pts2)) {
pts1.remove(j);
}
}
for (int j = 0; j < pts2.size(); j++) {
if (pointInPolygon(pts2.get(j), pts1)) {
pts2.remove(j);
}
}
pts.addAll(pts1);
pts.addAll(pts2);
}
}
// This part didn't work
// PolygonOptions range = new PolygonOptions();
// range.addAll(pts);
// range.strokeWidth(0);
// range.fillColor(0x7F729E47);
// activity.range.add(activity.mMap.addPolygon(range));
您需要计算行的缓冲区。根据Wikipedia:
A buffer is an area defined by the bounding region determined by a set of points at a specified maximum distance from all nodes along segments of an object.
几何的缓冲区是使用 Minkowski sum 计算的。 Minkowsky 求和采用两个多边形(一个是折线,另一个是圆形,如果你想要圆角)并移动第二个通过第一个的路径。
您可以找到一些您可以研究的 Minkowski 和的具体实现。例如https://github.com/perelo/computational-geometry/blob/master/src/computational_geometry/model/algorithms/Minkowski.java
按照@antonio 的指示,并使用 JTS Topology Suit,我能够在路线周围绘制一个具有定义半径的多边形(缓冲路线)。当我使用 JTS 库中的缓冲区函数时,我获得了路线的缓冲区,但上限是椭圆形的,我读到了它,发生这种情况是因为计算的坐标投影在不平坦的地球地图上,上限变得更椭圆当路线靠近地球两极时,当靠近赤道线(0º 纬度)时更圆。无论如何,我使用了库中的另一个功能来合并我的问题中已有的所有多边形,结果如下:
public ArrayList<Polygon> polys = new ArrayList<>();
//lineOptions is the set of route coordinates
for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
// Draw a circle around each point of the route
PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);
// Draw a convex hull between every two successive circles
PolygonOptions convexHull = convexHull(circle1, circle2);
List<LatLng> latLngs = convexHull.getPoints();
List<Coordinate> coords = new ArrayList<>();
for (int j=0; j<latLngs.size(); j++) {
coords.add(new Coordinate(latLngs.get(j).latitude, latLngs.get(j).longitude));
if(j==latLngs.size()-1)
coords.add(new Coordinate(latLngs.get(0).latitude, latLngs.get(0).longitude));
}
Coordinate[] coordinates = coords.toArray(new Coordinate[coords.size()]);
GeometryFactory fact = new GeometryFactory();
LinearRing linear = new GeometryFactory().createLinearRing(coordinates);
Polygon poly = new Polygon(linear, null, fact);
polys.add(poly);
}
PolygonOptions combine = combineIntoOnePolygon(polys);
combine.strokeWidth(0);
combine.fillColor(0x7F729E47);
activity.range = activity.mMap.addPolygon(combine);
合并函数:
static PolygonOptions combineIntoOnePolygon(Collection<Polygon> geometries ){
Geometry all = null;
PolygonOptions allPolygon = new PolygonOptions();
for(Iterator<Polygon> i = geometries.iterator(); i.hasNext(); ){
Polygon geometry = i.next();
if( geometry == null ) continue;
if( all == null ){
all = geometry;
}
else {
all = all.union( geometry );
}
}
List<Coordinate> bufferCoordinates = Arrays.asList(all.getCoordinates());
for (Coordinate c : bufferCoordinates) {
allPolygon.add(new LatLng(c.x, c.y));
}
return allPolygon;
}