在项目中用到在地图上绘图进行区域标记,为了便于存储这些区域的绘图信息,以及方便其他GIS工具识别,于是采用WTK标记语言作为空间图形存储,可以方便地将点、圆、多边形的经纬度转成可识别的字符串存储到数据库中,以及从数据库中读取这些数据,转换成经纬度上图。
需要用到的jar包
gt-api-19.1.jar
gt-main-19.1.jar
gt-metadata-19.1.jar
gt-referencing-19.1.jar
jts-core-1.14.0.jar
jts-io-1.14.0.jar
或者通过maven管理:
<!-- geometry -->
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts-core</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts-io</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>2.7.4-GBE-276</version>
</dependency>
实现代码
/**
* 基于JTS实现对空间绘图的WTK语言标记
*/
public class GeometryDemo {
private static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
/**
* 将字符串转成{@code Point}对象
*
* @param pointStr 形如{@code POINT (1.1,1.2)}
* @return
* @see Point
*/
public static Point createPoint(String pointStr) {
checkArgument(Objects.nonNull(pointStr), "pointStr must not be null.");
WKTReader reader = new WKTReader(geometryFactory);
Point point = null;
try {
point = (Point) reader.read(pointStr);
} catch (ParseException e) {
e.printStackTrace();
}
return point;
}
/**
* 将一个经纬度转成{@code Point}对象
*
* @param longitude 经度
* @param latitude 纬度
* @return
*/
public static Point createPoint(double longitude, double latitude) {
return createPoint(createPointString(new WarpLatitude(longitude, latitude)));
}
/**
* 将WKT标记的点转换成经纬度对象
*
* @param pointStr
* @return
*/
public static WarpLatitude pointToLonLan(String pointStr) {
Point point = createPoint(pointStr);
return new WarpLatitude(point.getX(), point.getY());
}
/**
* 将WKT字符串转换成Polygon对象
*
* @param areaStr
* @return
*/
public static Polygon createPolygon(String areaStr) {
WKTReader reader = new WKTReader(geometryFactory);
Polygon polygon = null;
try {
polygon = (Polygon) reader.read(areaStr);
} catch (ParseException e) {
e.printStackTrace();
}
return polygon;
}
/**
* 根据给定的经纬度创建一个面
*
* @param longitude1 第一个点的经度
* @param latitude1 第一个点的纬度
* @param longitude2 第二个点的经度
* @param latitude2 第二个点的纬度
* @param longitude3 第三个点的经度
* @param latitude3 第三个点的纬度
* @param longlan 其他点的经纬度,必须成对出现
* @return
*/
public static Polygon craetePolygon(double longitude1, double latitude1, double longitude2, double latitude2, double longitude3, double latitude3, double... longlan) {
List<WarpLatitude> latitudes = Lists.newArrayList();
latitudes.add(new WarpLatitude(longitude1, latitude1));
latitudes.add(new WarpLatitude(longitude2, latitude2));
latitudes.add(new WarpLatitude(longitude3, latitude3));
if (longlan != null && longlan.length > 0) {
if (longlan.length % 2 != 0) {
throw new IllegalArgumentException("其他点的经纬度必须成对出现");
}
int cursor = 0;
double longitude = 0d, latitude = 0d;
for (int i = 0; i < longlan.length; i++) {
if (i % 2 == 0) {
longitude = longlan[i];
} else {
latitude = longlan[i];
}
if (cursor == 1) {
latitudes.add(new WarpLatitude(longitude, latitude));
cursor = 0;
} else {
cursor++;
}
}
}
return createPolygon(createPolygonString(latitudes));
}
/**
* 将WKT标记的面转换成经纬度集合
*
* @param polygonStr
* @return
*/
public static List<WarpLatitude> polygonToLonLans(String polygonStr) {
Polygon polygon = createPolygon(polygonStr);
Coordinate[] coordinates = polygon.getCoordinates();
List<WarpLatitude> warpLatitudes = Lists.newArrayListWithCapacity(coordinates.length);
for (int i = 0; i < coordinates.length; i++) {
Coordinate coordinate = coordinates[i];
warpLatitudes.add(new WarpLatitude(coordinate.x, coordinate.y));
}
return warpLatitudes;
}
/**
* 将一个经纬度数据转换成WKT能够解读的点的字符串
*
* @param warpLatitude
* @return
*/
private static String createPointString(WarpLatitude warpLatitude) {
return "POINT (" + warpLatitude + ")";
}
/**
* 将多个经纬度数据转换成一个面
*
* @param warpLatitudes
* @return
*/
private static String createPolygonString(List<WarpLatitude> warpLatitudes) {
StringBuilder polygons = new StringBuilder("POLYGON((");
polygons.append(Joiner.on(",").join(warpLatitudes));
polygons.append("))");
return polygons.toString();
}
private static class WarpLatitude {
/**
* 经度
*/
private double longitude;
/**
* 纬度
*/
private double latitude;
public WarpLatitude(double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
@Override
public String toString() {
return this.longitude + " " + this.latitude;
}
}
}