求凹多边形的视觉中心,不是质心、重心
思路都是google上找的
思路1:效果不是很好,勉强可以
/**
* reference:http://stackoverflow.com/questions/25495560/how-can-i-find-the-best-place-to-fit-a-label-inside-a-polygon
* refernce:https://www.mapbox.com/blog/polygon-center/
* 1.Create four polygons by translating the original one with w, -w, h, -h where w and h are the semi-width and semi-height of the label.
2.Intersect those four polygons.
3.if the intersection is null - the label won't fit in the polygon. Exit.
4.All points inside the intersection satisfy the requirement: place the center of the label in one of those points.
* @param polygon
* @return
*/
static public Geometry getPolygonVisualPoint(Polygon polygon){
Coordinate[] coordinates = polygon.getCoordinates();
List<Coordinate> leftCoordinateList = Arrays.asList(deepCopy(coordinates));
List<Coordinate> rightCoordinateList = Arrays.asList(deepCopy(coordinates));
List<Coordinate> topCoordinateList = Arrays.asList(deepCopy(coordinates));
List<Coordinate> bottomCoordinateList = Arrays.asList(deepCopy(coordinates));
Envelope envelope = polygon.getEnvelopeInternal();
double h = envelope.getHeight();
double w = envelope.getWidth();
double minSize = Math.min(h,w)/2;
translateCoord(leftCoordinateList,true,minSize*-1);
translateCoord(rightCoordinateList,true,minSize*1);
translateCoord(topCoordinateList,false,minSize*1);
translateCoord(bottomCoordinateList,false,minSize*-1);
Polygon leftPolygon = createPolygon(leftCoordinateList);
Polygon rightPolygon = createPolygon(rightCoordinateList);
Polygon topPolygon = createPolygon(topCoordinateList);
Polygon bottomPolygon = createPolygon(bottomCoordinateList);
List<Geometry> polygons = new ArrayList<>();
polygons.add(polygon);
polygons.add(leftPolygon);
polygons.add(rightPolygon);
polygons.add(topPolygon);
polygons.add(bottomPolygon);
Geometry geometry = intersect(polygons);
return geometry;
}
static public Geometry intersect(List<Geometry> geoms){
Geometry intersectRes = geoms.get(0);
for(int i=1;i<geoms.size();i++){
if(intersectRes.intersects(geoms.get(i))){
intersectRes = intersectRes.intersection(geoms.get(i));
}
}
return intersectRes;
}
static private Coordinate[] deepCopy(Coordinate[] arr){
Coordinate[] dest = new Coordinate[arr.length];
int i=0;
for(Coordinate coordinate : arr){
dest[i++] = (Coordinate) coordinate.clone();
}
return dest;
}
static public Polygon createPolygon(List<Coordinate> list){
Coordinate[] arr = new Coordinate[list.size()];
list.toArray(arr);
return createPolygon(arr);
}
static public Polygon createPolygon(Coordinate[] coordinates){
GeometryFactory geometryFactory = new GeometryFactory();
Polygon polygon = geometryFactory.createPolygon(geometryFactory.createLinearRing(coordinates),null);
return polygon;
}
static private void translateCoord(List<Coordinate> coordinates,boolean isX,double delta){
for(Coordinate coordinate : coordinates){
if(isX){
coordinate.x += delta;
}else {
coordinate.y += delta;
}
}
}
思路2
http://stackoverflow.com/questions/4279478/largest-circle-inside-a-non-convex-polygon
https://github.com/mapbox/polylabel/blob/master/polylabel.js--这里有使用的demo,重点是求中心时注意设置精度,如果单位是经纬度,建议0.001
https://github.com/mourner/tinyqueue/blob/master/index.js--tinyquene