一些高级的操作
- 几何形状Geometry缓冲(buffer)
- 线段的融合(linemerge)是将Geometry A中相互连接的线段进行连接
- 多边形化操作(polygonize)对Geometry A进行计算,返回一个多边形(Polygon)。将由许多个点表示的图形,用少量的点来表示,减少图形的信息,即对图形进行降维
- 凹壳分析,包含几何形体的所有点的最小凸壳多边形(外包多边形)
相关的代码实现
- 工厂
package com.alibaba.autonavi;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryFactory {
private WKTReader reader;
private static GeometryFactory instance = null;
public static synchronized GeometryFactory getInstance(){
if(instance==null){
instance = new GeometryFactory();
}
return instance;
}
public void getReader(){
reader = new WKTReader();
}
public Geometry buildGeometryByWkt(String str){
try {
if(reader==null){
reader = new WKTReader();
}
return reader.read(str);
} catch (ParseException e) {
throw new RuntimeException("buildGeometry Error",e);
}
}
}
- buffer操作
buffer在GIS中是用于计算Geometry的给定距离内包含所有点的区域的操作
package com.alibaba.autonavi;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.buffer.BufferOp;
/**
* bufferdemo
* @author xingxing.dxx
*
*/
public class BufferDemo {
private static GeometryFactory factory = GeometryFactory.getInstance();
public static void main(String[] args) {
BufferDemo bs = new BufferDemo();
String line = "LINESTRING (0 0, 1 1, 2 2,3 3)";
Geometry g1 = factory.buildGeometryByWkt(line);
//方式(一)
Geometry g = g1.buffer(2);
////方式(二) BufferOP
BufferOp bufOp = new BufferOp(g1);
bufOp.setEndCapStyle(BufferOp.CAP_BUTT);
Geometry bg = bufOp.getResultGeometry(2);
}
}
- Polygonization
package com.alibaba.autonavi;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.polygonize.Polygonizer;
public class Polygonization {
private static GeometryFactory factory = GeometryFactory.getInstance();
public static void main(String[] args) {
List<Geometry> list = new ArrayList<Geometry>();
list.add(factory.buildGeometryByWkt("LINESTRING (0 0,1 1)"));
list.add(factory.buildGeometryByWkt("LINESTRING (6 3,6 10)"));
list.add(factory.buildGeometryByWkt("LINESTRING (2 2,4 4,6 3)"));
list.add(factory.buildGeometryByWkt("LINESTRING (2 2,5 1,6 3)"));
list.add(factory.buildGeometryByWkt("LINESTRING (6 3,6 4)"));
list.add(factory.buildGeometryByWkt("LINESTRING (9 5,7 1,6 4)"));
list.add(factory.buildGeometryByWkt("LINESTRING (9 5,8 8,6 4)"));
Polygonizer p = new Polygonizer();
p.add(list);
Collection<Geometry> polys = p.getPolygons(); //面
Collection<Geometry> dangles = p.getDangles();//悬挂线
Collection<Geometry> cuts = p.getCutEdges(); //面和面的连接线
System.out.println(polys.size()+":"+polys.toString());
System.out.println(dangles.size()+":"+dangles.toString());
System.out.println(cuts.size()+":"+cuts.toString());
}
}
- MergerLine
package com.alibaba.autonavi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.operation.linemerge.LineMerger;
public class MergerLine {
private static GeometryFactory factory = GeometryFactory.getInstance();
public static void main(String[] args) {
LineMerger lineMerger = new LineMerger();
List<Geometry> list = new ArrayList<Geometry>();
list.add(factory.buildGeometryByWkt("LINESTRING (3 3,2 2,0 0)"));
list.add(factory.buildGeometryByWkt("LINESTRING (3 3,6 6,0 10)"));
list.add(factory.buildGeometryByWkt("LINESTRING (0 10,3 1,10 1)"));
lineMerger.add(list);
Collection<Geometry> mergerLineStrings = lineMerger.getMergedLineStrings();
for (Geometry g : mergerLineStrings) {
System.out.println(g.toText());
}
}
}
package com.alibaba.autonavi;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Geometry;
public class UnionLine {
private static GeometryFactory factory = GeometryFactory.getInstance();
public static void main(String[] args) {
List<Geometry> list = new ArrayList<Geometry>();
list.add(factory.buildGeometryByWkt("LINESTRING (10 10,2 2,0 0)"));
list.add(factory.buildGeometryByWkt("LINESTRING (10 0,6 6,0 10)"));
list.add(factory.buildGeometryByWkt("LINESTRING (1 1,3 1,10 1)"));
Geometry nodedLine = list.get(0);
for (int i = 1; i < list.size(); i++) {
nodedLine = nodedLine.union(list.get(i));
}
int num = nodedLine.getNumGeometries();
for (int j = 0; j < num; j++) {
Geometry eachG = nodedLine.getGeometryN(j);
System.out.println(eachG.toText());
}
}
}
注意点
在使用buffer的时候发现一个比较奇怪的现象
如下图所示:link和求出的 buffer
通过检查输入数据,发现是因为 link的坐标是无序的,所以才出现了这个问题
lng lat
1 119.53290332862665 35.392994649858394
2 119.532898 35.393353
3 119.532898 35.39335233694318
最后附上上述图形相关的生成R语言代码
library(rgeos)
library(leaflet)
wkt <- "POLYGON ((119.53264429320605 35.393349227408265, 119.53277114660303 35.39335111370413, 119.53293568134956 35.39335233694318, 119.53264426515858 35.39335233694318, 119.53264426515858 35.393353, 119.53265656750867 35.3934310494835, 119.53269228159844 35.39350153049857, 119.53274794422803 35.39355760849212, 119.5328181577851 35.3935938455739, 119.532896113652 35.39360672782946, 119.53297425243832 35.3935950060648, 119.53304499701589 35.39355981694096, 119.53310148727397 35.39350457275179, 119.53313824534494 35.39343463053341, 119.53315170679396 35.39335677259173, 119.5331570354206 35.39299842245013, 119.53264962183269 35.39299087726666, 119.53264429320605 35.393349227408265))"
readWKT(wkt) -> polygon
linestring <- "LINESTRING (119.53290332862665 35.392994649858394, 119.532898 35.393353, 119.532898 35.39335233694318)"
readWKT(linestring) -> line
point_str <- "POINT (119.532856 35.393564)"
readWKT(point_str) -> point
leaflet() %>% addPolygons(data = polygon) %>% addPolylines(data = line)