zoukankan      html  css  js  c++  java
  • 求凹多边形的视觉中心,不是质心、重心

    思路都是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

  • 相关阅读:
    centos7 install flash player
    【转载】网站配置Https证书系列(二):IIS服务器给网站配置Https证书
    【转载】网站配置Https证书系列(一):腾讯云申请免费的SSL证书的流程步骤(即https安全连接使用的证书)
    【转载】网站配置Https证书系列(三):IIS网站设置Http链接直接跳转Https安全连接
    【转载】 C#使用Union方法求两个List集合的并集数据
    【转载】程序设计过程中SQL语句Where 1=1的作用
    【转载】C#编程中两个List集合使用Intersect方法求交集
    【转载】腾讯云服务器域名解析操作详解
    【转载】C#中使用OrderBy和ThenBy等方法对List集合进行排序
    【转载】腾讯云服务器通过设置安全组放行对外端口号
  • 原文地址:https://www.cnblogs.com/yinchuanqi/p/6805320.html
Copyright © 2011-2022 走看看