摘要:基于切割多邊形實現思路初稿詳見多邊形等分依賴實現實現過程結果類泰森多邊形平分多邊形結果原始平面隨機點集合分組后組中心集合構造泰森多邊形聚合類聚合聚合總量數據集合簇族數量中
基于K-means 切割多邊形 JAVA實現
思路初稿詳見多邊形等分
依賴geotools
ekmeans
實現過程org.locationtech.jts jts-core 1.16.0 junit junit 4.12 test org.geotools gt-shapefile ${geotools.version} org.geotools gt-main ${geotools.version} org.geotools gt-swing ${geotools.version} org.geotools gt-geojson ${geotools.version} org.geotools gt-geometry ${geotools.version} com.vividsolutions jts 1.13 org.geotools gt-geojson ${geotools.version} ca.pjer ekmeans 2.0.0 compile
結果類 KmeanPolygonResult
package com.huifer.planar.asEt.entity; import java.util.ArrayList; import java.util.List; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; /** *Title : KmeanPolygonResult
*Description : Kmean+泰森多邊形平分多邊形結果
* * @author huifer * @date 2019-01-16 */ @Data @NoArgsConstructor @AllArgsConstructor public class KmeanPolygonResult { /** * 原始平面 */ private Polygon polygon; /** * 隨機點集合 */ private ArrayListpointList; /** * 分組后組id */ private int[] assignments; /** * 中心集合 */ private double[][] centroids; /** * xlist */ private ArrayList xlist; /** * ylist */ private ArrayList ylist; /** * 構造泰森多邊形 */ private List voronoi; }
k-means 聚合類
package com.huifer.planar.asEt.utils; import ca.pjer.ekmeans.EKmeans; import lombok.Data; /** *Title : Kmeans
*Description : Kmeans 聚合
* * @author huifer * @date 2019-01-15 */ @Data public class Kmeans { /*** * 聚合總量 */ private int n; /*** * 數據集合 */ private double[][] points; /** * 簇族數量 */ private int k; /** * 中心集合 */ private double[][] centroids; /** * 分組后組id */ private int[] assignments; public Kmeans(double[][] points, int k) { this.n = points.length; this.points = points; this.k = k; this.centroids = new double[k][2]; init(); } /** * 求得分組數據 */ public void init() { EKmeans eKmeans = new EKmeans(centroids, points); eKmeans.setIteration(128); eKmeans.setEqual(true); eKmeans.setDistanceFunction(EKmeans.EUCLIDEAN_DISTANCE_FUNCTION); eKmeans.run(); int[] assignments = eKmeans.getAssignments(); this.assignments = assignments; double[][] centroids = eKmeans.getCentroids(); this.centroids = centroids; } }
泰森多邊形構造
package com.huifer.planar.asEt.algo.impl; import com.huifer.planar.asEt.algo.VoronoiInterface; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.geotools.geometry.jts.JTSFactoryFinder; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.locationtech.jts.triangulate.VoronoiDiagramBuilder; import org.locationtech.jts.triangulate.quadedge.QuadEdgeSubdivision; /** *Title : VoronoiInterfaceImpl
*Description : 泰森多邊形 & 德勞內三角形
* * @author huifer * @date 2019-01-16 */ public class VoronoiInterfaceImpl implements VoronoiInterface { @Override public Listvoronoi(double[][] doubles) { return voronoi(doublesToCoordinate(doubles)); } @Override public Collection delaunay(double[][] doubles) { return delaunay(doublesToCoordinate(doubles)); } @Override public List voronoi(ArrayList points) { List voronoi = voronoi(pointToCoordinate(points)); return voronoi; } @Override public Collection delaunay(ArrayList points) { Collection delaunay = delaunay(pointToCoordinate(points)); return delaunay; } private List doublesToCoordinate(double[][] doubles) { List coords = new ArrayList (); for (int i = 0; i < doubles.length; i++) { Coordinate coord = new Coordinate(doubles[i][0], doubles[i][1], i); coords.add(coord); } return coords; } private List pointToCoordinate(ArrayList points) { List coords = new ArrayList (); for (int i = 0; i < points.size(); i++) { Coordinate coord = new Coordinate(points.get(i).getX(), points.get(i).getY(), i); coords.add(coord); } return coords; } private VoronoiDiagramBuilder getVoronoiDiagramBuilder(List coords) { VoronoiDiagramBuilder voronoiDiagramBuilder = new VoronoiDiagramBuilder(); Envelope clipEnvelpoe = new Envelope(); voronoiDiagramBuilder.setSites(coords); voronoiDiagramBuilder.setClipEnvelope(clipEnvelpoe); return voronoiDiagramBuilder; } @Override public List voronoi(List coords) { VoronoiDiagramBuilder voronoiDiagramBuilder = getVoronoiDiagramBuilder( coords); Geometry geom = voronoiDiagramBuilder .getDiagram(JTSFactoryFinder.getGeometryFactory()); List voronoi = new ArrayList<>(); int numGeometries = geom.getNumGeometries(); for (int i = 0; i < numGeometries; i++) { Geometry geometryN = geom.getGeometryN(i); voronoi.add(geometryN); } return voronoi; } @Override public Collection delaunay(List coords) { VoronoiDiagramBuilder voronoiDiagramBuilder = getVoronoiDiagramBuilder(coords); QuadEdgeSubdivision subdivision = voronoiDiagramBuilder.getSubdivision(); Collection delaunay = subdivision.getEdges(); return delaunay; } }
Kmeans 切割面類
package com.huifer.planar.asEt.algo.impl; import com.huifer.planar.asEt.algo.KmeanPolygonSplitInterface; import com.huifer.planar.asEt.algo.VoronoiInterface; import com.huifer.planar.asEt.entity.KmeanPolygonResult; import com.huifer.planar.asEt.utils.Kmeans; import com.huifer.planar.asEt.utils.shptools.overlay.Operation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.io.ParseException; /** *結果展示 注Title : KmeanPolygonSplitCore
*Description : Kmean split polygon core
* * @author huifer * @date 2019-01-16 */ public class KmeanPolygonSplitCore implements KmeanPolygonSplitInterface { private static double random(double max, double min) { double d = (Math.random() * (max - min) + min); return d; } @Override public KmeanPolygonResult splitPolygon(String wkt, int setp, int k) throws ParseException { Operation op = new Operation(); KmeanPolygonResult result = new KmeanPolygonResult(); Polygon polygon = op.createPolygonByWKT(wkt); Coordinate[] coordinates = polygon.getCoordinates(); ArrayListxList = new ArrayList<>(); ArrayList yList = new ArrayList<>(); Arrays.stream(coordinates).forEach( s -> { xList.add(s.x); yList.add(s.y); } ); // xy 最大最小值 Double xMax = xList.stream().reduce(Double::max).get(); Double xMin = xList.stream().reduce(Double::min).get(); Double yMax = yList.stream().reduce(Double::max).get(); Double yMin = yList.stream().reduce(Double::min).get(); // 當前點數量 int pointCount = 0; ArrayList pointArrayList = new ArrayList<>(); for (int i = 0; i < Integer.MAX_VALUE; i++) { // 最大最小值隨機 if (pointCount <= setp) { double rx = random(xMax, xMin); double ry = random(yMax, yMin); Point nowPoint = op.createPointByWkt("POINT(" + rx + " " + ry + ")"); boolean contains = polygon.contains(nowPoint); if (contains) { pointArrayList.add(nowPoint); pointCount++; } } else { break; } } // k-means 數據 構造 double[][] kmData = new double[pointArrayList.size()][2]; for (int i = 0; i < pointArrayList.size(); i++) { Point point = pointArrayList.get(i); double[] oneData = new double[2]; oneData[0] = point.getX(); oneData[1] = point.getY(); kmData[i] = oneData; } // k-means 結果 Kmeans kmeans = new Kmeans(kmData, k); // 構造泰森多邊形 VoronoiInterface vo = new VoronoiInterfaceImpl(); List voronoi = vo.voronoi(kmeans.getCentroids()); result.setPolygon(polygon); result.setPointList(pointArrayList); result.setAssignments(kmeans.getAssignments()); result.setCentroids(kmeans.getCentroids()); result.setXlist(xList); result.setYlist(yList); result.setVoronoi(voronoi); return result; } }
本文代碼及可視化代碼均放在 gitee 碼云上 歡迎star & fork
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73041.html
摘要:網上已經有很多關于正六邊形的畫法,主要是利用一個矩形和前后的兩個三角形組合而成。是內容區,是一個菱形切割區,將切割成六邊形。的高度,多排六邊形的情況下,的高度與排與排之間的間隙有關。的高度,六邊形對應頂點間的距離。網上已經有很多關于正六邊形的CSS畫法,主要是利用一個矩形和前后的兩個三角形組合而成。 之前在看四維圖新的官網的時候,發現了一種六邊形的畫法,比較適合多排六邊形組合成蜂窩狀的展示區...
摘要:在自然語言處理中,一個很重要的技術手段就是將文檔轉換為一個矢量,這個過程一般是使用這個庫進行處理的。自然語言處理中,一般來說,代表詞。自然語言預處理中,一個很重要的步驟就是將你收集的句子進行分詞,將一個句子分解成詞的列表。 前言 本文根據實際項目撰寫,由于項目保密要求,源代碼將進行一定程度的刪減。本文撰寫的目的是進行公司培訓,請勿以任何形式進行轉載。由于是日語項目,用到的分詞軟件等,在...
摘要:其實聚類算法還有一個妙用就是,當數據集過于龐大,并且原始數據并不存在信息,你又需要跑一個有監督學習的算法的時候,你想要人為的給數據打顯然是不合適的,這時先跑一次聚類,記錄好聚類的情況,再直接跑有監督學習的算法就可以了。 前言 在本系列前面的內容中,講述了一系列的機器學習方法。要知道機器學習算法中,比較常用的主要分成有監督學習和無監督學習(其實還有一個叫半監督學習,在這里先不作討論),簡...
閱讀 2216·2021-09-07 09:58
閱讀 3391·2019-08-30 14:07
閱讀 1305·2019-08-29 12:32
閱讀 667·2019-08-29 11:06
閱讀 3692·2019-08-26 18:18
閱讀 3731·2019-08-26 17:35
閱讀 1381·2019-08-26 11:35
閱讀 611·2019-08-26 11:35